From 49fff2d9b47a51e0f2f600602aaa2fddc234b4be Mon Sep 17 00:00:00 2001 From: caternuson Date: Thu, 9 Apr 2020 08:37:07 -0700 Subject: [PATCH 01/42] initial working fill --- shared-bindings/displayio/Bitmap.c | 19 ++++++++++++++++++ shared-bindings/displayio/Bitmap.h | 1 + shared-module/displayio/Bitmap.c | 32 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 91c17f2d13..48d04c2157 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -178,9 +178,28 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } +//| .. method:: fill() +//| +//| Fills the bitmap. +//| +STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t value = mp_obj_get_int(value_obj); + if (value >= 1 << common_hal_displayio_bitmap_get_bits_per_value(self)) { + mp_raise_ValueError(translate("pixel value requires too many bits")); + } + common_hal_displayio_bitmap_fill(self, value); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); + STATIC const mp_rom_map_elem_t displayio_bitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_bitmap_height_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_bitmap_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&displayio_bitmap_fill_obj) }, + }; STATIC MP_DEFINE_CONST_DICT(displayio_bitmap_locals_dict, displayio_bitmap_locals_dict_table); diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 90694951fa..46c3373292 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -41,5 +41,6 @@ uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); +void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 59971d25cc..2b0165f2f7 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -162,3 +162,35 @@ void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; } + +void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + + for (uint32_t x=0; xwidth; x++) { + for (uint32_t y=0; yheight; y++) { + int32_t row_start = y * self->stride; + uint32_t bytes_per_value = self->bits_per_value / 8; + if (bytes_per_value < 1) { + uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); + uint32_t index = row_start + (x >> self->x_shift); + uint32_t word = self->data[index]; + word &= ~(self->bitmask << bit_position); + word |= (value & self->bitmask) << bit_position; + self->data[index] = word; + } else { + size_t* row = self->data + row_start; + if (bytes_per_value == 1) { + ((uint8_t*) row)[x] = value; + } else if (bytes_per_value == 2) { + ((uint16_t*) row)[x] = value; + } else if (bytes_per_value == 4) { + ((uint32_t*) row)[x] = value; + } + } + } + } + + self->dirty_area.x1 = 0; + self->dirty_area.x2 = self->width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = self->height; +} From dc7574684297cd3812fdb82967d0dfa7443af027 Mon Sep 17 00:00:00 2001 From: caternuson Date: Thu, 9 Apr 2020 08:59:26 -0700 Subject: [PATCH 02/42] add docstring, clean up --- shared-bindings/displayio/Bitmap.c | 4 ++-- shared-module/displayio/Bitmap.c | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 48d04c2157..391f3e5955 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -178,9 +178,9 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| .. method:: fill() +//| .. method:: fill(value) //| -//| Fills the bitmap. +//| Fills the bitmap with the supplied palette index value. //| STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 2b0165f2f7..503c360730 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -164,11 +164,21 @@ void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { } void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + // Update the dirty area. + self->dirty_area.x1 = 0; + self->dirty_area.x2 = self->width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = self->height; + // Update our data + int32_t row_start; + uint32_t bytes_per_value = self->bits_per_value / 8; for (uint32_t x=0; xwidth; x++) { for (uint32_t y=0; yheight; y++) { - int32_t row_start = y * self->stride; - uint32_t bytes_per_value = self->bits_per_value / 8; + row_start = y * self->stride; if (bytes_per_value < 1) { uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); uint32_t index = row_start + (x >> self->x_shift); @@ -188,9 +198,4 @@ void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) } } } - - self->dirty_area.x1 = 0; - self->dirty_area.x2 = self->width; - self->dirty_area.y1 = 0; - self->dirty_area.y2 = self->height; } From f817bfe3c6d66c9b5ebd673aeef2e4cf773c70be Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 23 Mar 2020 08:40:20 -0500 Subject: [PATCH 03/42] switch to checkout@v2 with submodules and fetch-depth 0 In order to get tags, including in submodules, we use our own fetching procedure on top of checkout@v2. A problem occuring in about 1% of jobs was that some submodules inexplicably did not have an "origin" remote configured. "git submodule sync" configures the "origin" remote in those cases. No cause for the problem was determined. Besides keeping up to date on actions/checkout, @v2 is supposed to fix a bug where "re-run" of a pull request would fail checking out the code. --- .github/workflows/build.yml | 33 ++++++++++++++++++------- .github/workflows/create_website_pr.yml | 7 ++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fc6ce5a47..ddd41412f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,16 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" + - uses: actions/checkout@v2 + with: + submodules: true + fetch-depth: 0 + - run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/* + - run: git submodule sync + - run: git submodule foreach git remote -v + - run: git submodule foreach git fetch --recurse-submodules=no origin +refs/tags/*:refs/tags/* + - name: CircuitPython version + run: git describe --dirty --tags - name: Set up Python 3.8 uses: actions/setup-python@v1 with: @@ -29,11 +39,6 @@ jobs: run: | gcc --version python3 --version - - uses: actions/checkout@v1 - with: - submodules: true - - name: CircuitPython version - run: git describe --dirty --always --tags - name: Build mpy-cross run: make -C mpy-cross -j2 - name: Build unix port @@ -103,11 +108,16 @@ jobs: gcc --version python3 --version msgfmt --version - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: true + fetch-depth: 0 + - run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/* + - run: git submodule sync + - run: git submodule foreach git remote -v + - run: git submodule foreach git fetch --recurse-submodules=no origin +refs/tags/*:refs/tags/* - name: CircuitPython version - run: git describe --dirty --always --tags + run: git describe --dirty --tags - name: Build mpy-cross run: make -C mpy-cross -j2 - uses: actions/upload-artifact@v1.0.0 @@ -260,9 +270,14 @@ jobs: gcc --version arm-none-eabi-gcc --version python3 --version - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: true + fetch-depth: 0 + - run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/* + - run: git submodule sync + - run: git submodule foreach git remote -v + - run: git submodule foreach git fetch --recurse-submodules=no origin +refs/tags/*:refs/tags/* - name: mpy-cross run: make -C mpy-cross -j2 - name: build @@ -325,4 +340,4 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - if: github.event_name == 'push' || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')) \ No newline at end of file + if: github.event_name == 'push' || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')) diff --git a/.github/workflows/create_website_pr.yml b/.github/workflows/create_website_pr.yml index 963fadd3dd..da4dad1790 100644 --- a/.github/workflows/create_website_pr.yml +++ b/.github/workflows/create_website_pr.yml @@ -23,11 +23,14 @@ jobs: run: | gcc --version python3 --version - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: true + fetch-depth: 0 + - run: git fetch --recurse-submodules=no https://github.com/adafruit/circuitpython refs/tags/*:refs/tags/* + - run: git submodule foreach git fetch --recurse-submodules=no origin +refs/tags/*:refs/tags/* - name: CircuitPython version - run: git describe --dirty --always --tags + run: git describe --dirty --tags - name: Website run: python3 build_board_info.py working-directory: tools From a9fb34eb93ff19df1bcf6498d492a31fd00c2c96 Mon Sep 17 00:00:00 2001 From: caternuson Date: Mon, 13 Apr 2020 16:48:27 -0700 Subject: [PATCH 04/42] make packed word and copy it in --- shared-module/displayio/Bitmap.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 503c360730..8bcda6086f 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -173,29 +173,13 @@ void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) self->dirty_area.y1 = 0; self->dirty_area.y2 = self->height; - // Update our data - int32_t row_start; - uint32_t bytes_per_value = self->bits_per_value / 8; - for (uint32_t x=0; xwidth; x++) { - for (uint32_t y=0; yheight; y++) { - row_start = y * self->stride; - if (bytes_per_value < 1) { - uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); - uint32_t index = row_start + (x >> self->x_shift); - uint32_t word = self->data[index]; - word &= ~(self->bitmask << bit_position); - word |= (value & self->bitmask) << bit_position; - self->data[index] = word; - } else { - size_t* row = self->data + row_start; - if (bytes_per_value == 1) { - ((uint8_t*) row)[x] = value; - } else if (bytes_per_value == 2) { - ((uint16_t*) row)[x] = value; - } else if (bytes_per_value == 4) { - ((uint32_t*) row)[x] = value; - } - } - } + // build the packed word + uint32_t word = 0; + for (uint8_t i=0; i<32 / self->bits_per_value; i++) { + word |= (value & self->bitmask) << (32 - ((i+1)*self->bits_per_value)); + } + // copy it in + for (uint32_t i=0; istride * self->height; i++) { + self->data[i] = word; } } From ca9796470115cef7ec22e9f59a3e68c319a5c32e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 16:03:35 -0500 Subject: [PATCH 05/42] ulab: Get updates from upstream --- extmod/ulab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extmod/ulab b/extmod/ulab index a91b36986d..22813d6736 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit a91b36986d81fd906a6232010778f2a93d690f8e +Subproject commit 22813d673691490b74ba21b57a1853fbfcbfac5b From d1a2a1a33374441cb619f4d2ff5d3a3c503975c6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 16:18:42 -0500 Subject: [PATCH 06/42] test requires yield, can't run native --- tests/run-tests | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-tests b/tests/run-tests index f6c727a8a6..6e980f03ce 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -385,6 +385,7 @@ def run_tests(pyb, tests, args, base_path=".", num_threads=1): skip_tests.add('stress/gc_trace.py') # requires yield skip_tests.add('stress/recursive_gen.py') # requires yield skip_tests.add('extmod/vfs_userfs.py') # because native doesn't properly handle globals across different modules + skip_tests.add('../extmod/ulab/tests/argminmax.py') # requires yield def run_one_test(test_file): test_file = test_file.replace('\\', '/') From d19700e975cb73f66863d2b735843318fdad353e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 17:17:51 -0500 Subject: [PATCH 07/42] make translate --- locale/ID.po | 32 +++++++++----------------------- locale/circuitpython.pot | 32 +++++++++----------------------- locale/de_DE.po | 32 +++++++++----------------------- locale/en_US.po | 32 +++++++++----------------------- locale/en_x_pirate.po | 32 +++++++++----------------------- locale/es.po | 32 +++++++++----------------------- locale/fil.po | 32 +++++++++----------------------- locale/fr.po | 32 +++++++++----------------------- locale/it_IT.po | 32 +++++++++----------------------- locale/ko.po | 32 +++++++++----------------------- locale/pl.po | 32 +++++++++----------------------- locale/pt_BR.po | 32 +++++++++----------------------- locale/zh_Latn_pinyin.po | 32 +++++++++----------------------- 13 files changed, 117 insertions(+), 299 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 619f7e6b75..ab8aa844c8 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -900,6 +900,7 @@ msgid "Invalid number of bits" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "" @@ -931,6 +932,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1647,6 +1649,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "" @@ -2158,10 +2164,6 @@ msgstr "" msgid "full" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "fungsi tidak dapat mengambil argumen keyword" @@ -2175,10 +2177,6 @@ msgstr "fungsi diharapkan setidaknya %d argumen, hanya mendapatkan %d" msgid "function got multiple values for argument '%q'" msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2659,14 +2657,6 @@ msgstr "modul tidak ditemukan" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2676,10 +2666,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3095,7 +3081,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3107,7 +3093,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 177eee2bf0..a421b4ef18 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -889,6 +889,7 @@ msgid "Invalid number of bits" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "" @@ -920,6 +921,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1624,6 +1626,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "" @@ -2134,10 +2140,6 @@ msgstr "" msgid "full" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "" @@ -2151,10 +2153,6 @@ msgstr "" msgid "function got multiple values for argument '%q'" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2634,14 +2632,6 @@ msgstr "" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2651,10 +2641,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3069,7 +3055,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3081,7 +3067,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/de_DE.po b/locale/de_DE.po index 351da58936..ec343d7f20 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -897,6 +897,7 @@ msgid "Invalid number of bits" msgstr "Ungültige Anzahl von Bits" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Ungültige Phase" @@ -928,6 +929,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Ungültige Polarität" @@ -1652,6 +1654,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "Array/Bytes auf der rechten Seite erforderlich" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "Attribute werden noch nicht unterstützt" @@ -2163,10 +2169,6 @@ msgstr "" msgid "full" msgstr "voll" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "Funktion akzeptiert keine Keyword-Argumente" @@ -2180,10 +2182,6 @@ msgstr "Funktion erwartet maximal %d Argumente, aber hat %d erhalten" msgid "function got multiple values for argument '%q'" msgstr "Funktion hat mehrere Werte für Argument '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2670,14 +2668,6 @@ msgstr "offset außerhalb der Grenzen" msgid "only bit_depth=16 is supported" msgstr "nur eine bit_depth=16 wird unterstützt" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "nur eine sample_rate=16000 wird unterstützt" @@ -2687,10 +2677,6 @@ msgstr "nur eine sample_rate=16000 wird unterstützt" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3114,7 +3100,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3126,7 +3112,7 @@ msgid "wrong number of values to unpack" msgstr "falsche Anzahl zu entpackender Werte" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/en_US.po b/locale/en_US.po index 095d175ebd..a28fc10302 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -889,6 +889,7 @@ msgid "Invalid number of bits" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "" @@ -920,6 +921,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1624,6 +1626,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "" @@ -2134,10 +2140,6 @@ msgstr "" msgid "full" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "" @@ -2151,10 +2153,6 @@ msgstr "" msgid "function got multiple values for argument '%q'" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2634,14 +2632,6 @@ msgstr "" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2651,10 +2641,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3069,7 +3055,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3081,7 +3067,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index a7f00a7b2e..946c3af24f 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -893,6 +893,7 @@ msgid "Invalid number of bits" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "" @@ -924,6 +925,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1628,6 +1630,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "" @@ -2138,10 +2144,6 @@ msgstr "" msgid "full" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "" @@ -2155,10 +2157,6 @@ msgstr "" msgid "function got multiple values for argument '%q'" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2638,14 +2636,6 @@ msgstr "" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2655,10 +2645,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3073,7 +3059,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3085,7 +3071,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/es.po b/locale/es.po index 3f4313de93..f3f6c45914 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -897,6 +897,7 @@ msgid "Invalid number of bits" msgstr "Numero inválido de bits" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Fase inválida" @@ -928,6 +929,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Polaridad inválida" @@ -1648,6 +1650,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "array/bytes requeridos en el lado derecho" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "atributos aún no soportados" @@ -2165,10 +2171,6 @@ msgstr "format requiere un dict" msgid "full" msgstr "lleno" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "la función no tiene argumentos por palabra clave" @@ -2182,10 +2184,6 @@ msgstr "la función esperaba minimo %d argumentos, tiene %d" msgid "function got multiple values for argument '%q'" msgstr "la función tiene múltiples valores para el argumento '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2672,14 +2670,6 @@ msgstr "address fuera de límites" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2689,10 +2679,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "solo se admiten segmentos con step=1 (alias None)" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3110,7 +3096,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3122,7 +3108,7 @@ msgid "wrong number of values to unpack" msgstr "numero erroneo de valores a descomprimir" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/fil.po b/locale/fil.po index cd6f52c393..44da9b7557 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -905,6 +905,7 @@ msgid "Invalid number of bits" msgstr "Mali ang bilang ng bits" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Mali ang phase" @@ -936,6 +937,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Mali ang polarity" @@ -1657,6 +1659,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "array/bytes kinakailangan sa kanang bahagi" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "attributes hindi sinusuportahan" @@ -2179,10 +2185,6 @@ msgstr "kailangan ng format ng dict" msgid "full" msgstr "puno" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "ang function ay hindi kumukuha ng mga argumento ng keyword" @@ -2196,10 +2198,6 @@ msgstr "function na inaasahang %d ang argumento, ngunit %d ang nakuha" msgid "function got multiple values for argument '%q'" msgstr "ang function ay nakakuha ng maraming values para sa argument '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2685,14 +2683,6 @@ msgstr "wala sa sakop ang address" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2702,10 +2692,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "ang mga slices lamang na may hakbang = 1 (aka None) ang sinusuportahan" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3125,7 +3111,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3137,7 +3123,7 @@ msgid "wrong number of values to unpack" msgstr "maling number ng value na i-unpack" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/fr.po b/locale/fr.po index 64abb8f9fd..17746f41fd 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -911,6 +911,7 @@ msgid "Invalid number of bits" msgstr "Nombre de bits invalide" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Phase invalide" @@ -942,6 +943,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Polarité invalide" @@ -1674,6 +1676,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "tableau/octets requis à droite" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "attribut pas encore supporté" @@ -2204,10 +2210,6 @@ msgstr "le format nécessite un dict" msgid "full" msgstr "plein" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "la fonction ne prend pas d'arguments nommés" @@ -2221,10 +2223,6 @@ msgstr "la fonction attendait au plus %d arguments, reçu %d" msgid "function got multiple values for argument '%q'" msgstr "la fonction a reçu plusieurs valeurs pour l'argument '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2712,14 +2710,6 @@ msgstr "adresse hors limites" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2729,10 +2719,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "seules les tranches avec 'step=1' (cad None) sont supportées" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3159,7 +3145,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3171,7 +3157,7 @@ msgid "wrong number of values to unpack" msgstr "mauvais nombre de valeurs à dégrouper" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/it_IT.po b/locale/it_IT.po index 89fb9329e2..1717f20f95 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -907,6 +907,7 @@ msgid "Invalid number of bits" msgstr "Numero di bit non valido" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Fase non valida" @@ -938,6 +939,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Polarità non valida" @@ -1660,6 +1662,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "attributi non ancora supportati" @@ -2180,10 +2186,6 @@ msgstr "la formattazione richiede un dict" msgid "full" msgstr "pieno" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "la funzione non prende argomenti nominati" @@ -2197,10 +2199,6 @@ msgstr "la funzione prevede al massimo %d argmoneti, ma ne ha ricevuti %d" msgid "function got multiple values for argument '%q'" msgstr "la funzione ha ricevuto valori multipli per l'argomento '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2690,14 +2688,6 @@ msgstr "indirizzo fuori limite" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2707,10 +2697,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "solo slice con step=1 (aka None) sono supportate" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3132,7 +3118,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3144,7 +3130,7 @@ msgid "wrong number of values to unpack" msgstr "numero di valori da scompattare non corretto" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/ko.po b/locale/ko.po index d502e60c07..9a1770f33b 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -893,6 +893,7 @@ msgid "Invalid number of bits" msgstr "비트 수가 유효하지 않습니다" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "단계가 잘못되었습니다" @@ -924,6 +925,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1629,6 +1631,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "" @@ -2139,10 +2145,6 @@ msgstr "" msgid "full" msgstr "완전한(full)" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "" @@ -2156,10 +2158,6 @@ msgstr "" msgid "function got multiple values for argument '%q'" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2639,14 +2637,6 @@ msgstr "" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2656,10 +2646,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3074,7 +3060,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3086,7 +3072,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/pl.po b/locale/pl.po index 67eff44f3a..d26dff9416 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -894,6 +894,7 @@ msgid "Invalid number of bits" msgstr "Zła liczba bitów" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Zła faza" @@ -925,6 +926,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Zła polaryzacja" @@ -1632,6 +1634,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "tablica/bytes wymagane po prawej stronie" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "atrybuty nie są jeszcze obsługiwane" @@ -2143,10 +2149,6 @@ msgstr "format wymaga słownika" msgid "full" msgstr "pełny" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "funkcja nie bierze argumentów nazwanych" @@ -2160,10 +2162,6 @@ msgstr "funkcja bierze najwyżej %d argumentów, jest %d" msgid "function got multiple values for argument '%q'" msgstr "funkcja dostała wiele wartości dla argumentu '%q'" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2643,14 +2641,6 @@ msgstr "offset poza zakresem" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2660,10 +2650,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "tylko fragmenty ze step=1 (lub None) są wspierane" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3080,7 +3066,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3092,7 +3078,7 @@ msgid "wrong number of values to unpack" msgstr "zła liczba wartości do rozpakowania" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/pt_BR.po b/locale/pt_BR.po index c6fe5dcba2..153dadd910 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -900,6 +900,7 @@ msgid "Invalid number of bits" msgstr "Número inválido de bits" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Fase Inválida" @@ -931,6 +932,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "" @@ -1642,6 +1644,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "atributos ainda não suportados" @@ -2156,10 +2162,6 @@ msgstr "" msgid "full" msgstr "cheio" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "função não aceita argumentos de palavras-chave" @@ -2173,10 +2175,6 @@ msgstr "função esperada na maioria dos %d argumentos, obteve %d" msgid "function got multiple values for argument '%q'" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2656,14 +2654,6 @@ msgstr "" msgid "only bit_depth=16 is supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "" @@ -2673,10 +2663,6 @@ msgstr "" msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3093,7 +3079,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3105,7 +3091,7 @@ msgid "wrong number of values to unpack" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8be47eb864..d1c0d5b79c 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-03-30 17:03-0700\n" +"POT-Creation-Date: 2020-04-13 19:22-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -902,6 +902,7 @@ msgid "Invalid number of bits" msgstr "Wèi shù wúxiào" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid phase" msgstr "Jiēduàn wúxiào" @@ -933,6 +934,7 @@ msgid "Invalid pins for PWMOut" msgstr "" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c +#: shared-bindings/displayio/FourWire.c msgid "Invalid polarity" msgstr "Wúxiào liǎng jí zhí" @@ -1657,6 +1659,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "yòu cè xūyào shùzǔ/zì jié" +#: extmod/ulab/code/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" + #: py/objstr.c msgid "attributes not supported yet" msgstr "shǔxìng shàngwèi zhīchí" @@ -2171,10 +2177,6 @@ msgstr "géshì yāoqiú yīgè yǔjù" msgid "full" msgstr "chōngfèn" -#: extmod/ulab/code/linalg.c -msgid "function defined for ndarrays only" -msgstr "" - #: py/argcheck.c msgid "function does not take keyword arguments" msgstr "hánshù méiyǒu guānjiàn cí cānshù" @@ -2188,10 +2190,6 @@ msgstr "hánshù yùjì zuìduō %d cānshù, huòdé %d" msgid "function got multiple values for argument '%q'" msgstr "hánshù huòdé cānshù '%q' de duōchóng zhí" -#: extmod/ulab/code/linalg.c -msgid "function is defined for ndarrays only" -msgstr "" - #: py/argcheck.c #, c-format msgid "function missing %d required positional arguments" @@ -2673,14 +2671,6 @@ msgstr "piānlí biānjiè" msgid "only bit_depth=16 is supported" msgstr "Jǐn zhīchí wèi shēndù = 16" -#: extmod/ulab/code/linalg.c -msgid "only ndarray objects can be inverted" -msgstr "" - -#: extmod/ulab/code/linalg.c -msgid "only ndarrays can be inverted" -msgstr "" - #: ports/nrf/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" msgstr "Jǐn zhīchí cǎiyàng lǜ = 16000" @@ -2690,10 +2680,6 @@ msgstr "Jǐn zhīchí cǎiyàng lǜ = 16000" msgid "only slices with step=1 (aka None) are supported" msgstr "jǐn zhīchí bù zhǎng = 1(jí wú) de qiēpiàn" -#: extmod/ulab/code/linalg.c -msgid "only square matrices can be inverted" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/vectorise.c msgid "operands could not be broadcast together" msgstr "" @@ -3110,7 +3096,7 @@ msgid "wrong argument type" msgstr "" #: extmod/ulab/code/ndarray.c -msgid "wrong input type" +msgid "wrong index type" msgstr "" #: py/objstr.c @@ -3122,7 +3108,7 @@ msgid "wrong number of values to unpack" msgstr "wúfǎ jiě bāo de zhí shù" #: extmod/ulab/code/ndarray.c -msgid "wrong operand type on the right hand side" +msgid "wrong operand type" msgstr "" #: shared-module/displayio/Shape.c From db01f88cc32ddb307c09692eb28ef29389c774cb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 19:58:52 -0500 Subject: [PATCH 08/42] enable MICROPY_PY_REVERSE_SPECIAL_METHODS where ulab is enabled --- ports/cxd56/boards/spresense/mpconfigboard.h | 3 +++ ports/mimxrt10xx/mpconfigport.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ports/cxd56/boards/spresense/mpconfigboard.h b/ports/cxd56/boards/spresense/mpconfigboard.h index 0245e20450..c53f6b418c 100644 --- a/ports/cxd56/boards/spresense/mpconfigboard.h +++ b/ports/cxd56/boards/spresense/mpconfigboard.h @@ -36,3 +36,6 @@ #define DEFAULT_UART_BUS_RX (&pin_UART2_RXD) #define DEFAULT_UART_BUS_TX (&pin_UART2_TXD) + +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) + diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h index 745c12f7de..7e7df01230 100644 --- a/ports/mimxrt10xx/mpconfigport.h +++ b/ports/mimxrt10xx/mpconfigport.h @@ -44,7 +44,7 @@ extern uint8_t _ld_default_stack_size; #define MICROPY_PY_FUNCTION_ATTRS (0) #define MICROPY_PY_IO (1) #define MICROPY_PY_UJSON (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR ((uint32_t) &_ld_filesystem_start) From 693928d201c22338e34ffe9c8133f8f0f01ca617 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 20:10:02 -0500 Subject: [PATCH 09/42] doc updates --- shared-bindings/ulab/__init__.rst | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/shared-bindings/ulab/__init__.rst b/shared-bindings/ulab/__init__.rst index d8c10dcc86..c9f2617ff0 100644 --- a/shared-bindings/ulab/__init__.rst +++ b/shared-bindings/ulab/__init__.rst @@ -79,26 +79,30 @@ ulab.array -- 1- and 2- dimensional array .. method:: __add__() Adds corresponding elements of the two arrays, or adds a number to all - elements of the array. A number must be on the right hand side. If - both arguments are arrays, their sizes must match. + elements of the array. If both arguments are arrays, their sizes must match. .. method:: __sub__() - Subtracts corresponding elements of the two arrays, or subtracts a - number from all elements of the array. A number must be on the right - hand side. If both arguments are arrays, their sizes must match. + Subtracts corresponding elements of the two arrays, or adds a number to all + elements of the array. If both arguments are arrays, their sizes must match. .. method:: __mul__() Multiplies corresponding elements of the two arrays, or multiplies - all elements of the array by a number. A number must be on the right - hand side. If both arguments are arrays, their sizes must match. + all elements of the array by a number. If both arguments are arrays, + their sizes must match. .. method:: __div__() Multiplies corresponding elements of the two arrays, or divides - all elements of the array by a number. A number must be on the right - hand side. If both arguments are arrays, their sizes must match. + all elements of the array by a number. If both arguments are arrays, + their sizes must match. + + .. method:: __pow__() + + Computes the power (x**y) of corresponding elements of the the two arrays, + or one number and one array. If both arguments are arrays, their sizes + must match. .. method:: __getitem__() @@ -348,6 +352,12 @@ much more efficient than expressing the same operation as a Python loop. Return the total number of elements in the array, as an integer. +.. method:: trace(m) + + :param m: a square matrix + + Compute the trace of the matrix, the sum of its diagonal elements. + :mod:`ulab.filter` --- Filtering functions ========================================== @@ -404,11 +414,11 @@ operate over the flattened array (None), rows (0), or columns (1). .. method:: argmax(array, \*, axis=None) - Return the index of the maximum element of the 1D array, as an array with 1 element + Return the index of the maximum element of the 1D array .. method:: argmin(array, \*, axis=None) - Return the index of the minimum element of the 1D array, as an array with 1 element + Return the index of the minimum element of the 1D array .. method:: argsort(array, \*, axis=None) @@ -426,7 +436,7 @@ operate over the flattened array (None), rows (0), or columns (1). .. method:: max(array, \*, axis=None) - Return the maximum element of the 1D array, as an array with 1 element + Return the maximum element of the 1D array .. method:: mean(array, \*, axis=None) @@ -434,7 +444,7 @@ operate over the flattened array (None), rows (0), or columns (1). .. method:: min(array, \*, axis=None) - Return the minimum element of the 1D array, as an array with 1 element + Return the minimum element of the 1D array .. method:: roll(array, distance, \*, axis=None) From cc21bed0e40e10790478cb643b9e5bd831069804 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 16:03:35 -0500 Subject: [PATCH 10/42] ulab: Get updates from upstream --- extmod/ulab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extmod/ulab b/extmod/ulab index 22813d6736..a746bd8e09 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit 22813d673691490b74ba21b57a1853fbfcbfac5b +Subproject commit a746bd8e0953853056ee405e2fa02c8ebca4fb79 From 135fb5b8870050f8045dcea88c8896a1a35b493c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 14 Apr 2020 10:08:07 -0500 Subject: [PATCH 11/42] py.mk: update warning flags needed for ulab --- py/py.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/py.mk b/py/py.mk index bac237b7dd..bca6ac14c3 100644 --- a/py/py.mk +++ b/py/py.mk @@ -119,7 +119,7 @@ ulab.c \ vectorise.c \ ) CFLAGS_MOD += -DCIRCUITPY_ULAB=1 -DMODULE_ULAB_ENABLED=1 -$(BUILD)/extmod/ulab/code/%.o: CFLAGS += -Wno-sign-compare -Wno-missing-prototypes -Wno-unused-parameter -Wno-missing-declarations -Wno-error -Wno-shadow -Wno-maybe-uninitialized -DCIRCUITPY +$(BUILD)/extmod/ulab/code/%.o: CFLAGS += -Wno-float-equal -Wno-sign-compare -DCIRCUITPY endif # External modules written in C. From 6378d600c40d462836fd6599b9bdadf5e78df8f1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 28 Mar 2020 10:34:18 -0500 Subject: [PATCH 12/42] displayio: implement, use allocate_display_or_raise --- shared-bindings/displayio/Display.c | 13 ++----------- shared-bindings/displayio/EPaperDisplay.c | 13 ++----------- shared-module/displayio/__init__.c | 18 ++++++++++++++++++ shared-module/displayio/__init__.h | 3 +++ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 3ef7e74e9e..4c6e525b27 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -152,17 +152,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); } - displayio_display_obj_t *self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL || - displays[i].display.base.type == &mp_type_NoneType) { - self = &displays[i].display; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many displays")); - } + primary_display_t *disp = allocate_display_or_raise(); + displayio_display_obj_t *self = &disp->display;; self->base.type = &displayio_display_type; common_hal_displayio_display_construct( self, diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index 25a4a41e92..1459c16809 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -136,17 +136,8 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); } - displayio_epaperdisplay_obj_t *self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL || - displays[i].display.base.type == &mp_type_NoneType) { - self = &displays[i].epaper_display; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many displays")); - } + primary_display_t *disp = allocate_display_or_raise(); + displayio_epaperdisplay_obj_t *self = &disp->epaper_display;; mp_float_t refresh_time = mp_obj_get_float(args[ARG_refresh_time].u_obj); mp_float_t seconds_per_frame = mp_obj_get_float(args[ARG_seconds_per_frame].u_obj); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index efa61265e6..fd58a0322a 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -308,3 +308,21 @@ void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpos transformed->x1 = whole->x1 + (y1 - whole->y1); } } + +primary_display_t *allocate_display() { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t display_type = displays[i].display.base.type; + if (display_type == NULL || display_type == &mp_type_NoneType) { + return &displays[i]; + } + } + return NULL; + +primary_display_t *allocate_display_or_raise() { + primary_display_t *result = allocate_display(); + if (!result) { + mp_raise_RuntimeError(translate("Too many displays")); + } +} + +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index e78bc61ce4..4e1297c8d1 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -54,4 +54,7 @@ void displayio_background(void); void reset_displays(void); void displayio_gc_collect(void); +primary_display_t *allocate_display(void); +primary_display_t *allocate_display_or_raise(void); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H From 8cba145c90294a001ec5814fb501a7b96a055780 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 30 Mar 2020 10:47:14 -0500 Subject: [PATCH 13/42] displayio: implement, use allocate_new_display_bus_or_raise --- shared-bindings/displayio/FourWire.c | 13 +------------ shared-bindings/displayio/I2CDisplay.c | 13 +------------ shared-bindings/displayio/ParallelBus.c | 13 +------------ shared-module/displayio/__init__.c | 17 +++++++++++++++++ shared-module/displayio/__init__.h | 2 ++ 5 files changed, 22 insertions(+), 36 deletions(-) diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 77329578a4..1cd51b2e2d 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -82,19 +82,8 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); - displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].fourwire_bus.base.type == NULL || - displays[i].fourwire_bus.base.type == &mp_type_NoneType) { - self = &displays[i].fourwire_bus; - self->base.type = &displayio_fourwire_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_fourwire_obj_t* self = &allocate_display_bus_or_raise()->fourwire_bus; uint8_t polarity = args[ARG_polarity].u_int; if (polarity != 0 && polarity != 1) { diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 2e312aa14e..dd3333f6de 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -71,19 +71,8 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); - displayio_i2cdisplay_obj_t* self = NULL; mp_obj_t i2c = args[ARG_i2c_bus].u_obj; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].i2cdisplay_bus.base.type == NULL || - displays[i].i2cdisplay_bus.base.type == &mp_type_NoneType) { - self = &displays[i].i2cdisplay_bus; - self->base.type = &displayio_i2cdisplay_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_i2cdisplay_obj_t* self = &allocate_display_bus_or_raise()->i2cdisplay_bus; common_hal_displayio_i2cdisplay_construct(self, MP_OBJ_TO_PTR(i2c), args[ARG_device_address].u_int, reset); diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index b3a876f903..4d9ffb0a1e 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -83,18 +83,7 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t mcu_pin_obj_t *read = validate_obj_is_free_pin(args[ARG_read].u_obj); mcu_pin_obj_t *reset = validate_obj_is_free_pin(args[ARG_reset].u_obj); - displayio_parallelbus_obj_t* self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].parallel_bus.base.type== NULL || - displays[i].parallel_bus.base.type == &mp_type_NoneType) { - self = &displays[i].parallel_bus; - self->base.type = &displayio_parallelbus_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_parallelbus_obj_t* self = &allocate_display_bus_or_raise()->parallel_bus; common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); return self; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index fd58a0322a..4844dfe60b 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -326,3 +326,20 @@ primary_display_t *allocate_display_or_raise() { } } +primary_display_t *allocate_display_bus(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t display_type = displays[i].display.base.type; + if (display_type == NULL || display_type == &mp_type_NoneType) { + return &displays[i]; + } + } + return NULL; +} + +primary_display_t *allocate_display_bus_or_raise(void) { + primary_display_t *result = allocate_display_bus(); + if (result) { + return result; + } + mp_raise_RuntimeError(translate("Too many display busses")); +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 4e1297c8d1..638c2091e0 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -56,5 +56,7 @@ void displayio_gc_collect(void); primary_display_t *allocate_display(void); primary_display_t *allocate_display_or_raise(void); +primary_display_t *allocate_display_bus(void); +primary_display_t *allocate_display_bus_or_raise(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H From 094fe05bdd68332fa617df8a98858e324afa15ec Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 25 Mar 2020 13:40:48 -0500 Subject: [PATCH 14/42] allow retrieving info about a supervisor allocation --- supervisor/memory.h | 1 + supervisor/shared/memory.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/supervisor/memory.h b/supervisor/memory.h index f557744ae5..f4359ca46e 100755 --- a/supervisor/memory.h +++ b/supervisor/memory.h @@ -43,6 +43,7 @@ typedef struct { void memory_init(void); void free_memory(supervisor_allocation* allocation); +supervisor_allocation* allocation_from_ptr(void *ptr); supervisor_allocation* allocate_remaining_memory(void); // Allocate a piece of a given length in bytes. If high_address is true then it should be allocated diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 14c3b4979b..51037bd6d8 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -82,6 +82,15 @@ void free_memory(supervisor_allocation* allocation) { allocation->ptr = NULL; } +supervisor_allocation* allocation_from_ptr(void *ptr) { + for (size_t index = 0; index < CIRCUITPY_SUPERVISOR_ALLOC_COUNT; index++) { + if (allocations[index].ptr == ptr) { + return &allocations[index]; + } + } + return NULL; +} + supervisor_allocation* allocate_remaining_memory(void) { if (low_address == high_address) { return NULL; From a51d4f7a45ba19dfe419bbdd7f744ded50f0c38e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 31 Mar 2020 13:32:32 -0500 Subject: [PATCH 15/42] pycubed: add trailing newline to file POSIX specifies that text files end in a trailing newline --- ports/atmel-samd/boards/pycubed/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk index adbb4aedb9..14e6883c08 100644 --- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk @@ -21,4 +21,4 @@ CIRCUITPY_PS2IO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD \ No newline at end of file +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD From 09dc46a98480350b157636ffff8b89470f595f6e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 10 Mar 2020 13:12:01 -0500 Subject: [PATCH 16/42] Add Protomatter and FramebufferDisplay --- .gitmodules | 3 + lib/protomatter | 1 + .../boards/hallowing_m0_express/board.c | 1 + .../boards/hallowing_m4_express/board.c | 1 + .../boards/kicksat-sprite/mpconfigboard.mk | 2 + ports/atmel-samd/boards/monster_m4sk/board.c | 1 + ports/atmel-samd/boards/pewpew_m4/board.c | 1 + ports/atmel-samd/boards/pybadge/board.c | 1 + .../atmel-samd/boards/pybadge_airlift/board.c | 1 + .../boards/pycubed/mpconfigboard.mk | 2 + ports/atmel-samd/boards/pygamer/board.c | 1 + .../atmel-samd/boards/pygamer_advance/board.c | 1 + ports/atmel-samd/boards/pyportal/board.c | 1 + .../atmel-samd/boards/pyportal_titano/board.c | 3 +- .../boards/robohatmm1_m4/mpconfigboard.mk | 2 + ports/atmel-samd/boards/ugame10/board.c | 1 + .../mpconfigboard.mk | 2 + .../boards/winterbloom_sol/mpconfigboard.mk | 2 + .../common-hal/_protomatter/Protomatter.c | 77 +++ .../common-hal/_protomatter/Protomatter.h | 35 ++ .../common-hal/_protomatter/__init__.c | 0 .../common-hal/microcontroller/Pin.c | 12 + ports/atmel-samd/common-hal/pulseio/PWMOut.c | 27 +- ports/atmel-samd/mpconfigport.mk | 12 + ports/atmel-samd/peripherals | 2 +- ports/atmel-samd/timer_handler.c | 7 + ports/atmel-samd/timer_handler.h | 5 + .../nrf/boards/clue_nrf52840_express/board.c | 1 + ports/nrf/boards/ohs2020_badge/board.c | 1 + ports/stm/boards/meowbit_v121/board.c | 1 + py/circuitpy_defns.mk | 18 + py/circuitpy_mpconfig.h | 16 + py/circuitpy_mpconfig.mk | 11 + shared-bindings/_protomatter/Protomatter.c | 293 ++++++++++++ shared-bindings/_protomatter/Protomatter.h | 56 +++ shared-bindings/_protomatter/__init__.c | 55 +++ shared-bindings/displayio/Display.c | 9 +- shared-bindings/displayio/Display.h | 2 +- .../framebufferio/FramebufferDisplay.c | 452 ++++++++++++++++++ .../framebufferio/FramebufferDisplay.h | 74 +++ shared-bindings/framebufferio/__init__.c | 63 +++ shared-bindings/framebufferio/__init__.h | 0 shared-bindings/microcontroller/Pin.h | 6 + shared-module/_protomatter/Protomatter.c | 169 +++++++ shared-module/_protomatter/Protomatter.h | 0 shared-module/_protomatter/__init__.c | 0 shared-module/_protomatter/__init__.h | 0 shared-module/_protomatter/allocator.h | 30 ++ shared-module/displayio/ColorConverter.c | 11 +- shared-module/displayio/Display.c | 4 +- shared-module/displayio/EPaperDisplay.c | 2 +- shared-module/displayio/Palette.h | 1 + shared-module/displayio/__init__.c | 43 +- shared-module/displayio/__init__.h | 10 + shared-module/displayio/display_core.c | 46 +- shared-module/displayio/display_core.h | 2 +- .../framebufferio/FramebufferDisplay.c | 339 +++++++++++++ .../framebufferio/FramebufferDisplay.h | 82 ++++ shared-module/framebufferio/__init__.c | 0 shared-module/framebufferio/__init__.h | 0 tools/convert_release_notes.py | 3 + 61 files changed, 1954 insertions(+), 50 deletions(-) create mode 160000 lib/protomatter create mode 100644 ports/atmel-samd/common-hal/_protomatter/Protomatter.c create mode 100644 ports/atmel-samd/common-hal/_protomatter/Protomatter.h create mode 100644 ports/atmel-samd/common-hal/_protomatter/__init__.c create mode 100644 shared-bindings/_protomatter/Protomatter.c create mode 100644 shared-bindings/_protomatter/Protomatter.h create mode 100644 shared-bindings/_protomatter/__init__.c create mode 100644 shared-bindings/framebufferio/FramebufferDisplay.c create mode 100644 shared-bindings/framebufferio/FramebufferDisplay.h create mode 100644 shared-bindings/framebufferio/__init__.c create mode 100644 shared-bindings/framebufferio/__init__.h create mode 100644 shared-module/_protomatter/Protomatter.c create mode 100644 shared-module/_protomatter/Protomatter.h create mode 100644 shared-module/_protomatter/__init__.c create mode 100644 shared-module/_protomatter/__init__.h create mode 100644 shared-module/_protomatter/allocator.h create mode 100644 shared-module/framebufferio/FramebufferDisplay.c create mode 100644 shared-module/framebufferio/FramebufferDisplay.h create mode 100644 shared-module/framebufferio/__init__.c create mode 100644 shared-module/framebufferio/__init__.h diff --git a/.gitmodules b/.gitmodules index 365d9ff72f..ebff8ecb2a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -119,3 +119,6 @@ [submodule "ports/stm/st_driver"] path = ports/stm/st_driver url = https://github.com/hathach/st_driver.git +[submodule "lib/protomatter"] + path = lib/protomatter + url = https://github.com/adafruit/Adafruit_Protomatter diff --git a/lib/protomatter b/lib/protomatter new file mode 160000 index 0000000000..c3a3e35731 --- /dev/null +++ b/lib/protomatter @@ -0,0 +1 @@ +Subproject commit c3a3e35731d641cb5a21ae7319634afc419f5afe diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 0b44bd4bb1..9a1db9ca97 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -97,6 +97,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index 5dbdd499af..3e4a04ae22 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index 5429bcf86e..f7223790ac 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -11,8 +11,10 @@ LONGINT_IMPL = MPZ # Not needed. CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_NETWORK = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_AUDIOMP3 = 0 diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 684639c309..55d6f80c91 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 0f8936696f..cf8439cf0e 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -128,6 +128,7 @@ void board_init(void) { false, // pixels in byte share row. only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 257d72e30d..ffddf03977 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -100,6 +100,7 @@ void board_init(void) { false, // pixels in byte share row. only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c index 7df245a724..8274d0ebeb 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/board.c +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in byte share row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk index 14e6883c08..c14a296159 100644 --- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk @@ -15,7 +15,9 @@ LONGINT_IMPL = MPZ # Not needed. CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 7c3ca6e335..c7f2f6e1d8 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -100,6 +100,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c index 7fd3ebc5e1..6053fedb09 100644 --- a/ports/atmel-samd/boards/pygamer_advance/board.c +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index a86f0ee48a..ed3006e3cc 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -87,6 +87,7 @@ void board_init(void) { false, // pixels_in_byte_share_row (unused for depths > 8) 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c index a9ded1760d..40b7e84025 100644 --- a/ports/atmel-samd/boards/pyportal_titano/board.c +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -101,9 +101,10 @@ void board_init(void) { 0, // rotation 16, // Color depth false, // grayscale - false, // pixels_in_byte_share_row (unused for depths > 8) + false, // pixels_i|n_byte_share_row (unused for depths > 8) 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk index fd4f222306..57eb7f1b9c 100644 --- a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk @@ -17,7 +17,9 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 # Make room for more stuff CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_PROTOMATTER = 0 # Include these Python libraries in firmware. #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index 07814d558b..38661950f4 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -97,6 +97,7 @@ void board_init(void) { false, // pixels in byte share row. Only used with depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk index d91369f75e..691c1c1365 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk @@ -18,6 +18,7 @@ CIRCUITPY_AUDIOIO = 1 # Disable modules that are unusable on this special-purpose board. CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_AUDIOBUSIO = 0 @@ -27,6 +28,7 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_NETWORK = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_RTC = 0 diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk index 166eaad3f7..ed97aef4c0 100644 --- a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk @@ -21,10 +21,12 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_BLEIO = 0 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_NETWORK = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_USB_HID = 0 diff --git a/ports/atmel-samd/common-hal/_protomatter/Protomatter.c b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c new file mode 100644 index 0000000000..702de0e3d4 --- /dev/null +++ b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c @@ -0,0 +1,77 @@ +/* + * This file is part of the Micro Python 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 "common-hal/_protomatter/Protomatter.h" + +#include "samd/timers.h" +#include "timer_handler.h" + +void *common_hal_protomatter_timer_allocate() { + uint8_t timer_index = find_free_timer(); + if (timer_index == 0xff) { + return NULL; + } + timer_never_reset(timer_index, true); + return tc_insts[timer_index]; +} + +static uint8_t tc_index_from_ptr(void* ptr) { + for (uint8_t i = TC_INST_NUM; i > 0; i--) { + if (tc_insts[i] == ptr) { + return i; + } + } + return 0xff; +} + +void common_hal_protomatter_timer_enable(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + set_timer_handler(true, timer_index, TC_HANDLER_PROTOMATTER); + turn_on_clocks(true, timer_index, 1); +} + +void common_hal_protomatter_timer_disable(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + set_timer_handler(true, timer_index, TC_HANDLER_NO_INTERRUPT); +} + +void common_hal_protomatter_timer_free(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + tc_set_enable(ptr, false); + tc_reset(ptr); + timer_reset_ok(timer_index, true); +} diff --git a/ports/atmel-samd/common-hal/_protomatter/Protomatter.h b/ports/atmel-samd/common-hal/_protomatter/Protomatter.h new file mode 100644 index 0000000000..8185bed0e5 --- /dev/null +++ b/ports/atmel-samd/common-hal/_protomatter/Protomatter.h @@ -0,0 +1,35 @@ +/* + * This file is part of the Micro Python 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H + +void *common_hal_protomatter_timer_allocate(void); +void common_hal_protomatter_timer_enable(void*); +void common_hal_protomatter_timer_disable(void*); +void common_hal_protomatter_timer_free(void*); + +#endif diff --git a/ports/atmel-samd/common-hal/_protomatter/__init__.c b/ports/atmel-samd/common-hal/_protomatter/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 9719ea5b11..cf78673b20 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -240,3 +240,15 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { return pin_number_is_free(pin->number); } + +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) { + return pin->number; +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) { + return claim_pin(pin); +} + +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no); +} diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c index fef581584f..1da0da8444 100644 --- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -61,22 +61,31 @@ uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; -void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { - if (self->timer->is_tc) { - never_reset_tc_or_tcc[self->timer->index] += 1; +STATIC void timer_refcount(int index, bool is_tc, int increment) { + if (is_tc) { + never_reset_tc_or_tcc[index] += increment; } else { - never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] += 1; + never_reset_tc_or_tcc[TC_INST_NUM + index] += increment; } +} + +void timer_never_reset(int index, bool is_tc) { + timer_refcount(index, is_tc, 1); +} + +void timer_reset_ok(int index, bool is_tc) { + timer_refcount(index, is_tc, -1); +} + + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + timer_never_reset(self->timer->index, self->timer->is_tc); never_reset_pin_number(self->pin->number); } void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { - if (self->timer->is_tc) { - never_reset_tc_or_tcc[self->timer->index] -= 1; - } else { - never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] -= 1; - } + timer_reset_ok(self->timer->index, self->timer->is_tc); } void pwmout_reset(void) { diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index c2408feae3..61f7c206ab 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -70,6 +70,18 @@ CIRCUITPY_ULAB = 1 endif endif +ifndef CIRCUITPY_PROTOMATTER +ifneq ($(CIRCUITPY_SMALL_BUILD),1) +CIRCUITPY_PROTOMATTER = 1 +endif +endif + +ifndef CIRCUITPY_FRAMEBUFFERIO +ifneq ($(CIRCUITPY_SMALL_BUILD),1) +CIRCUITPY_FRAMEBUFFERIO = 1 +endif +endif + endif # samd51 INTERNAL_LIBM = 1 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index b89811f22a..f528240c2a 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit b89811f22a24ac350079ceaf0cdf0e62aa03f4f4 +Subproject commit f528240c2a4c2d7a39de786f1aa56895c12227b4 diff --git a/ports/atmel-samd/timer_handler.c b/ports/atmel-samd/timer_handler.c index 5d6de3093f..598fad564a 100644 --- a/ports/atmel-samd/timer_handler.c +++ b/ports/atmel-samd/timer_handler.c @@ -33,6 +33,8 @@ #include "shared-module/_pew/PewPew.h" #include "common-hal/frequencyio/FrequencyIn.h" +extern void _PM_IRQ_HANDLER(void); + static uint8_t tc_handler[TC_INST_NUM]; void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler) { @@ -62,6 +64,11 @@ void shared_timer_handler(bool is_tc, uint8_t index) { frequencyin_interrupt_handler(index); #endif break; + case TC_HANDLER_PROTOMATTER: + #if CIRCUITPY_PROTOMATTER + _PM_IRQ_HANDLER(); + #endif + break; default: break; } diff --git a/ports/atmel-samd/timer_handler.h b/ports/atmel-samd/timer_handler.h index 4a7adb58c3..646cd54ec8 100644 --- a/ports/atmel-samd/timer_handler.h +++ b/ports/atmel-samd/timer_handler.h @@ -30,8 +30,13 @@ #define TC_HANDLER_PULSEOUT 0x1 #define TC_HANDLER_PEW 0x2 #define TC_HANDLER_FREQUENCYIN 0x3 +#define TC_HANDLER_PROTOMATTER 0x4 void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler); void shared_timer_handler(bool is_tc, uint8_t index); +// implementation of these functions is in PWMOut.c +void timer_never_reset(int index, bool is_tc); +void timer_reset_ok(int index, bool is_tc); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index e9f8d244e4..2370a0aa1b 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index 88c68bcb84..bbb20cc6e5 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index 9e2d99bce0..68eed29269 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -98,6 +98,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index f84d0b5b1d..b6b0cacaf8 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -142,6 +142,9 @@ endif ifeq ($(CIRCUITPY_DISPLAYIO),1) SRC_PATTERNS += displayio/% terminalio/% fontio/% endif +ifeq ($(CIRCUITPY_FRAMEBUFFERIO),1) +SRC_PATTERNS += framebufferio/% +endif ifeq ($(CIRCUITPY_FREQUENCYIO),1) SRC_PATTERNS += frequencyio/% endif @@ -178,6 +181,9 @@ endif ifeq ($(CIRCUITPY_PIXELBUF),1) SRC_PATTERNS += _pixelbuf/% endif +ifeq ($(CIRCUITPY_PROTOMATTER),1) +SRC_PATTERNS += _protomatter/% +endif ifeq ($(CIRCUITPY_PULSEIO),1) SRC_PATTERNS += pulseio/% endif @@ -242,6 +248,8 @@ SRC_COMMON_HAL_ALL = \ _bleio/PacketBuffer.c \ _bleio/Service.c \ _bleio/UUID.c \ + _protomatter/Protomatter.c \ + _protomatter/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ @@ -315,6 +323,8 @@ SRC_SHARED_MODULE_ALL = \ _bleio/ScanResults.c \ _pixelbuf/PixelBuf.c \ _pixelbuf/__init__.c \ + _protomatter/Protomatter.c \ + _protomatter/__init__.c \ _stage/Layer.c \ _stage/Text.c \ _stage/__init__.c \ @@ -348,6 +358,8 @@ SRC_SHARED_MODULE_ALL = \ displayio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ + framebufferio/FramebufferDisplay.c \ + framebufferio/__init__.c \ gamepad/GamePad.c \ gamepad/__init__.c \ gamepadshift/GamePadShift.c \ @@ -401,6 +413,12 @@ SRC_MOD += $(addprefix lib/mp3/src/, \ ) $(BUILD)/lib/mp3/src/buffers.o: CFLAGS += -include "py/misc.h" -D'MPDEC_ALLOCATOR(x)=m_malloc(x,0)' -D'MPDEC_FREE(x)=m_free(x)' endif +ifeq ($(CIRCUITPY_PROTOMATTER),1) +SRC_MOD += $(addprefix lib/protomatter/, \ + core.c \ +) +$(BUILD)/lib/protomatter/core.o: CFLAGS += -include "shared-module/_protomatter/allocator.h" -DCIRCUITPY -Wno-missing-braces +endif # All possible sources are listed here, and are filtered by SRC_PATTERNS. SRC_SHARED_MODULE_INTERNAL = \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 04e1912643..06289258d1 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -345,6 +345,13 @@ extern const struct _mp_obj_module_t terminalio_module; #define CIRCUITPY_DISPLAY_LIMIT (0) #endif +#if CIRCUITPY_FRAMEBUFFERIO +extern const struct _mp_obj_module_t framebufferio_module; +#define FRAMEBUFFERIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_framebufferio), (mp_obj_t)&framebufferio_module }, +#else +#define FRAMEBUFFERIO_MODULE +#endif + #if CIRCUITPY_FREQUENCYIO extern const struct _mp_obj_module_t frequencyio_module; #define FREQUENCYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_frequencyio), (mp_obj_t)&frequencyio_module }, @@ -454,6 +461,13 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define PIXELBUF_MODULE #endif +#if CIRCUITPY_PROTOMATTER +extern const struct _mp_obj_module_t protomatter_module; +#define PROTOMATTER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__protomatter),(mp_obj_t)&protomatter_module }, +#else +#define PROTOMATTER_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 }, @@ -628,6 +642,7 @@ extern const struct _mp_obj_module_t ustack_module; FONTIO_MODULE \ TERMINALIO_MODULE \ ERRNO_MODULE \ + FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ GAMEPAD_MODULE \ GAMEPADSHIFT_MODULE \ @@ -643,6 +658,7 @@ extern const struct _mp_obj_module_t ustack_module; PEW_MODULE \ PIXELBUF_MODULE \ PS2IO_MODULE \ + PROTOMATTER_MODULE \ PULSEIO_MODULE \ RANDOM_MODULE \ RE_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 1a375efc65..ba94f9784f 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -149,6 +149,11 @@ CIRCUITPY_DISPLAYIO = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +ifndef CIRCUITPY_FRAMEBUFFERIO +CIRCUITPY_FRAMEBUFFERIO = 0 +endif +CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO) + ifndef CIRCUITPY_FREQUENCYIO CIRCUITPY_FREQUENCYIO = $(CIRCUITPY_FULL_BUILD) endif @@ -210,6 +215,12 @@ CIRCUITPY_PIXELBUF = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) +# Only for SAMD boards for the moment +ifndef CIRCUITPY_PROTOMATTER +CIRCUITPY_PROTOMATTER = 0 +endif +CFLAGS += -DCIRCUITPY_PROTOMATTER=$(CIRCUITPY_PROTOMATTER) + ifndef CIRCUITPY_PULSEIO CIRCUITPY_PULSEIO = $(CIRCUITPY_DEFAULT_BUILD) endif diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c new file mode 100644 index 0000000000..8d0d223bb5 --- /dev/null +++ b/shared-bindings/_protomatter/Protomatter.c @@ -0,0 +1,293 @@ +/* + * This file is part of the Micro Python 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/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objarray.h" + +#include "common-hal/_protomatter/Protomatter.h" +#include "shared-bindings/_protomatter/Protomatter.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +//| .. currentmodule:: _protomatter +//| +//| :class:`protomatter` -- Driver for HUB75-style RGB LED matrices +//| ================================================================ +//| + +extern Protomatter_core *_PM_protoPtr; + +STATIC uint8_t validate_pin(mp_obj_t obj) { + mcu_pin_obj_t *result = validate_obj_is_free_pin(obj); + return common_hal_mcu_pin_number(result); +} + +STATIC void validate_pins(qstr what, uint8_t* pin_nos, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out) { + mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); + if (len > max_pins) { + mp_raise_ValueError_varg(translate("At most %d %q may be specified"), max_pins, what); + } + *count_out = len; + for (mp_int_t i=0; iprotomatter; + self->base.type = &protomatter_Protomatter_type; + + uint8_t rgb_count, addr_count; + uint8_t rgb_pins[MP_ARRAY_SIZE(self->rgb_pins)]; + uint8_t addr_pins[MP_ARRAY_SIZE(self->addr_pins)]; + uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj); + uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj); + uint8_t oe_pin = validate_pin(args[ARG_oe_pin].u_obj); + + validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); + validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); + + mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; + if (framebuffer == mp_const_none) { + int width = args[ARG_width].u_int; + int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count); + framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); + } + + common_hal_protomatter_protomatter_construct(self, + args[ARG_width].u_int, + args[ARG_bit_depth].u_int, + rgb_count, rgb_pins, + addr_count, addr_pins, + clock_pin, latch_pin, oe_pin, + args[ARG_doublebuffer].u_bool, + framebuffer, NULL); + + claim_pins_nr(args[ARG_rgb_list].u_obj); + claim_pins_nr(args[ARG_addr_list].u_obj); + claim_pin_nr(args[ARG_clock_pin].u_obj); + claim_pin_nr(args[ARG_oe_pin].u_obj); + claim_pin_nr(args[ARG_latch_pin].u_obj); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit +//| +//| Free the resources (pins, timers, etc.) associated with this +//| protomatter instance. After deinitialization, no further operations +//| may be performed. +//| +STATIC mp_obj_t protomatter_protomatter_deinit(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + common_hal_protomatter_protomatter_deinit(self); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_deinit_obj, protomatter_protomatter_deinit); + +static void check_for_deinit(protomatter_protomatter_obj_t *self) { + if (!self->core.rgbPins) { + raise_deinited_error(); + } +} + +//| .. attribute:: paused +//| +//| When paused, the matrix is not driven and all its LEDs are unlit. +//| +STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + return mp_obj_new_bool(self->paused); +} +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); + +STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t value_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + bool paused = mp_obj_is_true(value_in); + if (paused && !self->paused) { + _PM_stop(&self->core); + } else if (!paused && self->paused) { + _PM_resume(&self->core); + } + self->paused = paused; + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_paused_obj, protomatter_protomatter_set_paused); + +const mp_obj_property_t protomatter_protomatter_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&protomatter_protomatter_get_paused_obj, + (mp_obj_t)&protomatter_protomatter_set_paused_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: write(buf) +//| +//| Transmits the color data in the buffer to the pixels so that they are shown. +//| +//| The data in the buffer must be in "RGB565" format. This means +//| that it is organized as a series of 16-bit numbers where the highest 5 +//| bits are interpreted as red, the next 6 as green, and the final 5 as +//| blue. The object can be any buffer, but `array.array` and `ulab.array` +//| objects are most often useful. +//| +STATIC mp_obj_t protomatter_protomatter_swapbuffers(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + _PM_swapbuffer_maybe(&self->core); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_swapbuffers_obj, protomatter_protomatter_swapbuffers); + +STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&protomatter_protomatter_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&protomatter_protomatter_paused_obj) }, + { MP_ROM_QSTR(MP_QSTR_swapbuffers), MP_ROM_PTR(&protomatter_protomatter_swapbuffers_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(protomatter_protomatter_locals_dict, protomatter_protomatter_locals_dict_table); + +STATIC void protomatter_protomatter_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + + *bufinfo = self->bufinfo; +} + +STATIC void protomatter_protomatter_swapbuffers_void(mp_obj_t self_in) { + protomatter_protomatter_swapbuffers(self_in); +} + +STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { + protomatter_protomatter_deinit(self_in); +} + +STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { + protomatter_protomatter_set_paused(self_in, mp_obj_new_bool(value <= 0)); +} + +STATIC const framebuffer_p_t protomatter_protomatter_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .get_bufinfo = protomatter_protomatter_get_bufinfo, + .set_brightness = protomatter_protomatter_set_brightness, + .swapbuffers = protomatter_protomatter_swapbuffers_void, + .deinit = protomatter_protomatter_deinit_void, +}; + +STATIC mp_int_t protomatter_protomatter_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_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; +} + +const mp_obj_type_t protomatter_Protomatter_type = { + { &mp_type_type }, + .name = MP_QSTR_Protomatter, + .buffer_p = { .get_buffer = protomatter_protomatter_get_buffer, }, + .make_new = protomatter_protomatter_make_new, + .protocol = &protomatter_protomatter_proto, + .locals_dict = (mp_obj_dict_t*)&protomatter_protomatter_locals_dict, +}; diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h new file mode 100644 index 0000000000..cacc39a304 --- /dev/null +++ b/shared-bindings/_protomatter/Protomatter.h @@ -0,0 +1,56 @@ +/* + * This file is part of the Micro Python 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PROTOMATTER_PROTOMATTER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PROTOMATTER_PROTOMATTER_H + +#include "shared-module/_protomatter/Protomatter.h" +#include "lib/protomatter/core.h" + +extern const mp_obj_type_t protomatter_Protomatter_type; +typedef struct { + mp_obj_base_t base; + mp_obj_t framebuffer; + mp_buffer_info_t bufinfo; + Protomatter_core core; + void *timer; + uint16_t bufsize, width; + uint8_t rgb_pins[30]; + uint8_t addr_pins[10]; + uint8_t clock_pin, latch_pin, oe_pin; + uint8_t rgb_count, addr_count; + uint8_t bit_depth; + bool core_is_initialized; + bool paused; + bool doublebuffer; +} protomatter_protomatter_obj_t; + +void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer); +void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t*); +void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); +void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); + +#endif diff --git a/shared-bindings/_protomatter/__init__.c b/shared-bindings/_protomatter/__init__.c new file mode 100644 index 0000000000..2281b15f10 --- /dev/null +++ b/shared-bindings/_protomatter/__init__.c @@ -0,0 +1,55 @@ +/* + * 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/_protomatter/Protomatter.h" + +//| :mod:`_protomatter` --- Low-level routines for bitbanged LED matrices +//| ===================================================================== +//| +//| .. module:: _protomatter +//| :synopsis: Low-level routines for bitbanged LED matrices +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Protomatter + +STATIC const mp_rom_map_elem_t protomatter_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__protomatter) }, + { MP_ROM_QSTR(MP_QSTR_Protomatter), MP_ROM_PTR(&protomatter_Protomatter_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(protomatter_module_globals, protomatter_module_globals_table); + +const mp_obj_module_t protomatter_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&protomatter_module_globals, +}; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 4c6e525b27..a22b2add22 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -92,6 +92,7 @@ //| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. //| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. //| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 //| :param int set_column_command: Command used to set the start and end columns to update //| :param int set_row_command: Command used so set the start and end rows to update //| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set. @@ -107,7 +108,7 @@ //| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on. //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high }; + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -121,6 +122,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, @@ -159,7 +161,10 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a self, display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, - args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_pixels_in_byte_share_row].u_bool, + args[ARG_bytes_per_cell].u_bool, + args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_reverse_bytes_in_word].u_bool, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, args[ARG_write_ram_command].u_int, args[ARG_set_vertical_scroll].u_int, diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 8c2e20262b..e69c5b6b52 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -41,7 +41,7 @@ extern const mp_obj_type_t displayio_display_type; void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, - bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, + bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, 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, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c new file mode 100644 index 0000000000..9f1df8bfaa --- /dev/null +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -0,0 +1,452 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: framebufferio +//| +//| :class:`FramebufferDisplay` -- Manage updating a display with framebuffer in RAM +//| ================================================================================ +//| +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. +//| +//| .. class:: FramebufferDisplay(framebuffer, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, backlight_pin=None, brightness=1.0, auto_brightness=False, auto_refresh=True, native_frames_per_second=60) +//| +//| Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc) +//| +//| :param framebuffer: The framebuffer that the display is connected to +//| :type framebuffer: any core object implementing the framebuffer protocol +//| :param callback: Function or bound method to call when the framebuffer has been updated. The callback receives one argument, the framebuffer object. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :param bool grayscale: True if the display only shows a single color. +//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. +//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. +//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight +//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True. +//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. +//| :param bool auto_refresh: Automatically refresh the screen +//| :param int native_frames_per_second: Number of display refreshes per second +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + }; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; + + const mcu_pin_obj_t* backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); + + mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); + } + + primary_display_t *disp = allocate_display_or_raise(); + framebufferio_framebufferdisplay_obj_t *self = &disp->framebuffer_display; + self->base.type = &framebufferio_framebufferdisplay_type; + common_hal_framebufferio_framebufferdisplay_construct( + self, + framebuffer, + args[ARG_width].u_int, args[ARG_height].u_int, + args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, + args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, + args[ARG_pixels_in_byte_share_row].u_bool, + args[ARG_bytes_per_cell].u_bool, + args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_reverse_bytes_in_word].u_bool, + MP_OBJ_TO_PTR(backlight_pin), + brightness, + args[ARG_auto_brightness].u_bool, + args[ARG_auto_refresh].u_bool, + args[ARG_native_frames_per_second].u_int + ); + + return self; +} + +// Helper to ensure we have the native super class instead of a subclass. +static framebufferio_framebufferdisplay_obj_t* native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &framebufferio_framebufferdisplay_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. +//| +//| :param Group group: The group to show. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_framebufferio_framebufferdisplay_show(self, group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebufferio_framebufferdisplay_obj_show); + +//| .. method:: refresh(*, target_frames_per_second=60, minimum_frames_per_second=1) +//| +//| When auto refresh is off, waits for the target frame rate and then refreshes the display, +//| returning True. If the call has taken too long since the last refresh call for the given +//| target frame rate, then the refresh returns False immediately without updating the screen to +//| hopefully help getting caught up. +//| +//| If the time since the last successful refresh is below the minimum frame rate, then an +//| exception will be raised. Set minimum_frames_per_second to 0 to disable. +//| +//| When auto refresh is on, updates the display immediately. (The display will also update +//| without calls to this.) +//| +//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated. +//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]); + uint32_t maximum_ms_per_real_frame = 0xffffffff; + mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; + if (minimum_frames_per_second > 0) { + maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; + } + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame)); +} +MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_refresh_obj, 1, framebufferio_framebufferdisplay_obj_refresh); + +//| .. attribute:: auto_refresh +//| +//| True when the display is refreshed automatically. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_refresh(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_refresh(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_refresh_obj, framebufferio_framebufferdisplay_obj_get_auto_refresh); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + + common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, mp_obj_is_true(auto_refresh)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_auto_refresh_obj, framebufferio_framebufferdisplay_obj_set_auto_refresh); + +const mp_obj_property_t framebufferio_framebufferdisplay_auto_refresh_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_auto_refresh_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_refresh_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: brightness +//| +//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When +//| `auto_brightness` is True, the value of `brightness` will change automatically. +//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_brightness(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + mp_float_t brightness = common_hal_framebufferio_framebufferdisplay_get_brightness(self); + if (brightness < 0) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_obj_new_float(brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_brightness_obj, framebufferio_framebufferdisplay_obj_get_brightness); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, false); + mp_float_t brightness = mp_obj_get_float(brightness_obj); + if (brightness < 0 || brightness > 1.0) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + bool ok = common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_brightness_obj, framebufferio_framebufferdisplay_obj_set_brightness); + +const mp_obj_property_t framebufferio_framebufferdisplay_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_brightness_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: auto_brightness +//| +//| True when the display brightness is adjusted automatically, based on an ambient +//| light sensor or other method. Note that some displays may have this set to True by default, +//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False +//| if `brightness` is set manually. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_brightness(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_brightness(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_brightness_obj, framebufferio_framebufferdisplay_obj_get_auto_brightness); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + + common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_auto_brightness_obj, framebufferio_framebufferdisplay_obj_set_auto_brightness); + +const mp_obj_property_t framebufferio_framebufferdisplay_auto_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_auto_brightness_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: width +//| +//| Gets the width of the framebuffer +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_width(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_width_obj, framebufferio_framebufferdisplay_obj_get_width); + +const mp_obj_property_t framebufferio_framebufferdisplay_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: height +//| +//| Gets the height of the framebuffer +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_height(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_height_obj, framebufferio_framebufferdisplay_obj_get_height); + +const mp_obj_property_t framebufferio_framebufferdisplay_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: rotation +//| +//| The rotation of the display as an int in degrees. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_rotation(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_rotation(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_rotation_obj, framebufferio_framebufferdisplay_obj_get_rotation); +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_rotation(mp_obj_t self_in, mp_obj_t value) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + common_hal_framebufferio_framebufferdisplay_set_rotation(self, mp_obj_get_int(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_rotation_obj, framebufferio_framebufferdisplay_obj_set_rotation); + + +const mp_obj_property_t framebufferio_framebufferdisplay_rotation_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_rotation_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_rotation_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: framebuffer +//| +//| The framebuffer being used by the display +//| +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_framebuffer(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return common_hal_framebufferio_framebufferdisplay_get_framebuffer(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_framebuffer_obj, framebufferio_framebufferdisplay_obj_get_framebuffer); + +const mp_obj_property_t framebufferio_framebufferframebuffer_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_framebuffer_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. method:: fill_row(y, buffer) +//| +//| Extract the pixels from a single row +//| +//| :param int y: The top edge of the area +//| :param bytearray buffer: The buffer in which to place the pixel data +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_y, ARG_buffer }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_y, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = -1} }, + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]); + mp_int_t y = args[ARG_y].u_int; + mp_obj_t *result = args[ARG_buffer].u_obj; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(result, &bufinfo, MP_BUFFER_WRITE); + + if (bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("Buffer is not a bytearray.")); + } + if (self->core.colorspace.depth != 16) { + mp_raise_ValueError(translate("Display must have a 16 bit colorspace.")); + } + + displayio_area_t area = { + .x1 = 0, + .y1 = y, + .x2 = self->core.width, + .y2 = y + 1 + }; + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t buffer_size = self->core.width / pixels_per_word; + uint16_t pixels_per_buffer = displayio_area_size(&area); + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + + uint32_t *result_buffer = bufinfo.buf; + size_t result_buffer_size = bufinfo.len; + + if (result_buffer_size >= (buffer_size * 4)) { + volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + + for (uint16_t k = 0; k < mask_length; k++) { + mask[k] = 0x00000000; + } + + displayio_display_core_fill_area(&self->core, &area, mask, result_buffer); + return result; + } else { + mp_raise_ValueError(translate("Buffer is too small")); + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_fill_row_obj, 1, framebufferio_framebufferdisplay_obj_fill_row); + +STATIC const mp_rom_map_elem_t framebufferio_framebufferdisplay_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&framebufferio_framebufferdisplay_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&framebufferio_framebufferdisplay_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill_row), MP_ROM_PTR(&framebufferio_framebufferdisplay_fill_row_obj) }, + + { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_refresh_obj) }, + + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_brightness_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&framebufferio_framebufferdisplay_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&framebufferio_framebufferdisplay_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_rotation), MP_ROM_PTR(&framebufferio_framebufferdisplay_rotation_obj) }, + { MP_ROM_QSTR(MP_QSTR_framebuffer), MP_ROM_PTR(&framebufferio_framebufferframebuffer_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(framebufferio_framebufferdisplay_locals_dict, framebufferio_framebufferdisplay_locals_dict_table); + +const mp_obj_type_t framebufferio_framebufferdisplay_type = { + { &mp_type_type }, + .name = MP_QSTR_FramebufferDisplay, + .make_new = framebufferio_framebufferdisplay_make_new, + .locals_dict = (mp_obj_dict_t*)&framebufferio_framebufferdisplay_locals_dict, +}; diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h new file mode 100644 index 0000000000..af0bd2c415 --- /dev/null +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -0,0 +1,74 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/framebufferio/FramebufferDisplay.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t framebufferio_framebufferdisplay_type; + +#define DELAY 0x80 + +#define NO_BRIGHTNESS_COMMAND 0x100 + +void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, + mp_obj_t framebuffer, uint16_t width, uint16_t height, + int16_t colstart, int16_t rowstart, + uint16_t rotation, 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, + const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, + bool auto_refresh, uint16_t native_frames_per_second); + +bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, + displayio_group_t* root_group); + +bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame); + +bool common_hal_framebufferio_framebufferdisplay_get_auto_refresh(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_framebufferdisplay_obj_t* self, bool auto_refresh); + +uint16_t common_hal_framebufferio_framebufferdisplay_get_width(framebufferio_framebufferdisplay_obj_t* self); +uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_framebufferdisplay_obj_t* self); +uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation); + +bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); + +bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); + +mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self); +bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness); + +mp_obj_t common_hal_framebufferio_framebufferdisplay_framebuffer(framebufferio_framebufferdisplay_obj_t* self); + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-bindings/framebufferio/__init__.c b/shared-bindings/framebufferio/__init__.c new file mode 100644 index 0000000000..0f0823a25f --- /dev/null +++ b/shared-bindings/framebufferio/__init__.c @@ -0,0 +1,63 @@ +/* + * 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/obj.h" +#include "shared-bindings/framebufferio/__init__.h" +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +//| :mod:`framebufferio` --- Native framebuffer display driving +//| ========================================================================= +//| +//| .. module:: framebufferio +//| :synopsis: Native helpers for driving displays +//| :platform: SAMD51, nRF52 +//| +//| The `framebufferio` module contains classes to manage display output +//| including synchronizing with refresh rates and partial updating. +//| It is used in conjunction with classes from `displayio` to actually +//| place items on the display; and classes like `Protomatter` to actually +//| drive the display. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| FramebufferDisplay +//| + +#if CIRCUITPY_FRAMEBUFFERIO +static const mp_rom_map_elem_t framebufferio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebufferio) }, + { MP_ROM_QSTR(MP_QSTR_FramebufferDisplay), MP_ROM_PTR(&framebufferio_framebufferdisplay_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(framebufferio_module_globals, framebufferio_module_globals_table); +const mp_obj_module_t framebufferio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&framebufferio_module_globals, +}; +#endif + diff --git a/shared-bindings/framebufferio/__init__.h b/shared-bindings/framebufferio/__init__.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 4f29322a06..bb5256b558 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -43,5 +43,11 @@ void assert_pin_free(const mcu_pin_obj_t* pin); bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin); void common_hal_never_reset_pin(const mcu_pin_obj_t* pin); void common_hal_reset_pin(const mcu_pin_obj_t* pin); +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin); +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin); +void common_hal_mcu_pin_claim_number(uint8_t pin_no); +void common_hal_mcu_pin_reset_number(uint8_t pin_no); + +#define COMMON_HAL_MCU_NO_PIN ((uint8_t)0xff) #endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c new file mode 100644 index 0000000000..cbb60db6d3 --- /dev/null +++ b/shared-module/_protomatter/Protomatter.c @@ -0,0 +1,169 @@ +/* + * This file is part of the Micro Python 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 "py/obj.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "common-hal/_protomatter/Protomatter.h" +#include "shared-module/_protomatter/allocator.h" +#include "shared-bindings/_protomatter/Protomatter.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +extern Protomatter_core *_PM_protoPtr; + +void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void *timer) { + self->width = width; + self->bit_depth = bit_depth; + self->rgb_count = rgb_count; + memcpy(self->rgb_pins, rgb_pins, rgb_count); + self->addr_count = addr_count; + memcpy(self->addr_pins, addr_pins, addr_count); + self->clock_pin = clock_pin; + self->oe_pin = oe_pin; + self->latch_pin = latch_pin; + self->doublebuffer = doublebuffer; + + self->timer = timer ? timer : common_hal_protomatter_timer_allocate(); + if (self->timer == NULL) { + mp_raise_ValueError(translate("No timer available")); + } + + self->width = width; + self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count); + + common_hal_protomatter_protomatter_reconstruct(self, framebuffer); +} + +void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer) { + if (framebuffer) { + self->framebuffer = framebuffer; + framebuffer = mp_obj_new_bytearray_of_zeros(self->bufsize); + mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ); + if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) { + self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; + } else { + self->bufinfo.typecode = 'H'; + } + // 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 { + self->framebuffer = NULL; + self->bufinfo.buf = _PM_allocator_impl(self->bufsize); + self->bufinfo.len = self->bufsize; + self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; + } + + ProtomatterStatus stat = _PM_init(&self->core, + self->width, self->bit_depth, + self->rgb_count/6, self->rgb_pins, + self->addr_count, self->addr_pins, + self->clock_pin, self->latch_pin, self->oe_pin, + self->doublebuffer, self->timer); + + if (stat == PROTOMATTER_OK) { + _PM_protoPtr = &self->core; + common_hal_mcu_disable_interrupts(); + common_hal_protomatter_timer_enable(self->timer); + stat = _PM_begin(&self->core); + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + common_hal_mcu_enable_interrupts(); + _PM_swapbuffer_maybe(&self->core); + } + + if (stat != PROTOMATTER_OK) { + // XXX this deinit() actually makes crashy-crashy + // can trigger it by sending inappropriate pins + common_hal_protomatter_protomatter_deinit(self); + switch (stat) { + case PROTOMATTER_ERR_PINS: + mp_raise_ValueError(translate("Invalid pin")); + break; + case PROTOMATTER_ERR_ARG: + mp_raise_ValueError(translate("Invalid argument")); + break; + case PROTOMATTER_ERR_MALLOC: /// should have already been signaled as NLR + default: + mp_raise_msg_varg(&mp_type_RuntimeError, + translate("Protomatter internal error #%d"), (int)stat); + break; + } + } + + self->paused = 0; + +} + +STATIC void free_pin(uint8_t *pin) { + if (*pin != COMMON_HAL_MCU_NO_PIN) { + common_hal_mcu_pin_reset_number(*pin); + } + *pin = COMMON_HAL_MCU_NO_PIN; +} + +STATIC void free_pin_seq(uint8_t *seq, int count) { + for (int i=0; itimer) { + common_hal_protomatter_timer_free(self->timer); + self->timer = 0; + } + + if (_PM_protoPtr == &self->core) { + _PM_protoPtr = NULL; + } + + free_pin_seq(self->rgb_pins, self->rgb_count); + free_pin_seq(self->addr_pins, self->addr_count); + free_pin(&self->clock_pin); + free_pin(&self->latch_pin); + free_pin(&self->oe_pin); + + if (self->core.rgbPins) { + _PM_free(&self->core); + } + + self->base.type = NULL; +} + +void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { + gc_collect_ptr(self->framebuffer); + gc_collect_ptr(self->core.rgbPins); + gc_collect_ptr(self->core.addr); + gc_collect_ptr(self->core.screenData); +} + diff --git a/shared-module/_protomatter/Protomatter.h b/shared-module/_protomatter/Protomatter.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/_protomatter/__init__.c b/shared-module/_protomatter/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/_protomatter/__init__.h b/shared-module/_protomatter/__init__.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h new file mode 100644 index 0000000000..8d9d7ff960 --- /dev/null +++ b/shared-module/_protomatter/allocator.h @@ -0,0 +1,30 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H +#define MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H + +#include +#include "py/misc.h" +#include "supervisor/memory.h" + +#define _PM_ALLOCATOR _PM_allocator_impl +#define _PM_FREE _PM_free_impl + +static inline void *_PM_allocator_impl(size_t sz) { + supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + if (allocation) { + return allocation->ptr; + } else { + return m_malloc(sz + sizeof(void*), true); + } +} + +static inline void _PM_free_impl(void *ptr_in) { + supervisor_allocation *allocation = allocation_from_ptr(ptr_in); + + if (allocation) { + free_memory(allocation); + } else { + m_free(ptr_in); + } +} + +#endif diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index a5d7f0b051..2c9fb6d789 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -47,9 +47,7 @@ uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) { uint32_t r5 = (color_rgb888 >> 19); uint32_t g6 = (color_rgb888 >> 10) & 0x3f; uint32_t b5 = (color_rgb888 >> 3) & 0x1f; - uint32_t packed = r5 << 11 | g6 << 5 | b5; - // swap bytes - return __builtin_bswap16(packed); + return r5 << 11 | g6 << 5 | b5; } uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) { @@ -156,7 +154,12 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d } if (colorspace->depth == 16) { - output_color->pixel = displayio_colorconverter_compute_rgb565(pixel); + uint16_t packed = displayio_colorconverter_compute_rgb565(pixel); + if (colorspace->reverse_bytes_in_word) { + // swap bytes + packed = __builtin_bswap16(packed); + } + output_color->pixel = packed; output_color->opaque = true; return; } else if (colorspace->tricolor) { diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 2edded9278..aaddbb4714 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -46,7 +46,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, - uint8_t bytes_per_cell, bool reverse_pixels_in_byte, uint8_t set_column_command, + uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, 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, @@ -60,7 +60,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, ram_height = 0xff; } displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, - color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte); + color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); self->set_column_command = set_column_command; self->set_row_command = set_row_command; diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c index 91d4bb7f9f..5b4a8f916b 100644 --- a/shared-module/displayio/EPaperDisplay.c +++ b/shared-module/displayio/EPaperDisplay.c @@ -58,7 +58,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); } - displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true); + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true, true); self->set_column_window_command = set_column_window_command; self->set_row_window_command = set_row_window_command; diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 758fd43fc1..da72f250f9 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -41,6 +41,7 @@ typedef struct { bool tricolor; bool pixels_in_byte_share_row; bool reverse_pixels_in_byte; + bool reverse_bytes_in_word; bool dither; } _displayio_colorspace_t; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 4844dfe60b..225aa2008e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -47,6 +47,10 @@ void displayio_background(void) { } if (displays[i].display.base.type == &displayio_display_type) { displayio_display_background(&displays[i].display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_background(&displays[i].framebuffer_display); +#endif } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_background(&displays[i].epaper_display); } @@ -67,6 +71,10 @@ void common_hal_displayio_release_displays(void) { release_display(&displays[i].display); } else if (display_type == &displayio_epaperdisplay_type) { release_epaperdisplay(&displays[i].epaper_display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (display_type == &framebufferio_framebufferdisplay_type) { + release_framebufferdisplay(&displays[i].framebuffer_display); +#endif } displays[i].display.base.type = &mp_type_NoneType; } @@ -141,6 +149,11 @@ void reset_displays(void) { } } } +#if CIRCUITPY_PROTOMATTER + } else if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_obj_t * pm = &displays[i].protomatter; + common_hal_protomatter_protomatter_reconstruct(pm, NULL); +#endif } else { // Not an active display bus. continue; @@ -155,12 +168,24 @@ void reset_displays(void) { } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display; common_hal_displayio_epaperdisplay_show(display, NULL); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display; + display->auto_refresh = true; + common_hal_framebufferio_framebufferdisplay_show(display, NULL); +#endif } } } void displayio_gc_collect(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { +#if CIRCUITPY_PROTOMATTER + if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_collect_ptrs(&displays[i].protomatter); + } +#endif + if (displays[i].display.base.type == NULL) { continue; } @@ -169,6 +194,10 @@ void displayio_gc_collect(void) { // but this is more precise, and is the only field that needs marking. if (displays[i].display.base.type == &displayio_display_type) { displayio_display_collect_ptrs(&displays[i].display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_collect_ptrs(&displays[i].framebuffer_display); +#endif } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_collect_ptrs(&displays[i].epaper_display); } @@ -309,7 +338,7 @@ void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpos } } -primary_display_t *allocate_display() { +primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_type = displays[i].display.base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { @@ -317,14 +346,14 @@ primary_display_t *allocate_display() { } } return NULL; - -primary_display_t *allocate_display_or_raise() { - primary_display_t *result = allocate_display(); - if (!result) { - mp_raise_RuntimeError(translate("Too many displays")); - } } +primary_display_t *allocate_display_or_raise(void) { + primary_display_t *result = allocate_display(); + if (result) { + return result; + } + mp_raise_RuntimeError(translate("Too many displays")); } primary_display_t *allocate_display_bus(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 638c2091e0..278a5e78f3 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -29,20 +29,30 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/EPaperDisplay.h" +#if CIRCUITPY_FRAMEBUFFERIO +#include "shared-bindings/framebufferio/FramebufferDisplay.h" +#endif #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/I2CDisplay.h" #include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/_protomatter/Protomatter.h" typedef struct { union { displayio_fourwire_obj_t fourwire_bus; displayio_i2cdisplay_obj_t i2cdisplay_bus; displayio_parallelbus_obj_t parallel_bus; +#if CIRCUITPY_PROTOMATTER + protomatter_protomatter_obj_t protomatter; +#endif }; union { displayio_display_obj_t display; displayio_epaperdisplay_obj_t epaper_display; +#if CIRCUITPY_FRAMEBUFFERIO + framebufferio_framebufferdisplay_obj_t framebuffer_display; +#endif }; } primary_display_t; diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index 120b70f76a..4cc7564d09 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -44,38 +44,42 @@ void displayio_display_core_construct(displayio_display_core_t* self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte) { + 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.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; + self->colorspace.reverse_bytes_in_word = reverse_bytes_in_word; self->colorspace.dither = false; self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; self->last_refresh = 0; - if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { - self->bus_reset = common_hal_displayio_parallelbus_reset; - self->bus_free = common_hal_displayio_parallelbus_bus_free; - self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; - self->send = common_hal_displayio_parallelbus_send; - self->end_transaction = common_hal_displayio_parallelbus_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { - self->bus_reset = common_hal_displayio_fourwire_reset; - self->bus_free = common_hal_displayio_fourwire_bus_free; - self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; - self->send = common_hal_displayio_fourwire_send; - self->end_transaction = common_hal_displayio_fourwire_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { - self->bus_reset = common_hal_displayio_i2cdisplay_reset; - self->bus_free = common_hal_displayio_i2cdisplay_bus_free; - self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; - self->send = common_hal_displayio_i2cdisplay_send; - self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction; - } else { - mp_raise_ValueError(translate("Unsupported display bus type")); + // (framebufferdisplay already validated its 'bus' is a buffer-protocol object) + if (bus) { + if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { + self->bus_reset = common_hal_displayio_parallelbus_reset; + self->bus_free = common_hal_displayio_parallelbus_bus_free; + self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; + self->send = common_hal_displayio_parallelbus_send; + self->end_transaction = common_hal_displayio_parallelbus_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { + self->bus_reset = common_hal_displayio_fourwire_reset; + self->bus_free = common_hal_displayio_fourwire_bus_free; + self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; + self->send = common_hal_displayio_fourwire_send; + self->end_transaction = common_hal_displayio_fourwire_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { + self->bus_reset = common_hal_displayio_i2cdisplay_reset; + self->bus_free = common_hal_displayio_i2cdisplay_bus_free; + self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; + self->send = common_hal_displayio_i2cdisplay_send; + self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction; + } else { + mp_raise_ValueError(translate("Unsupported display bus type")); + } } self->bus = bus; diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h index 1c3d0f09c6..e4fd62d4a5 100644 --- a/shared-module/displayio/display_core.h +++ b/shared-module/displayio/display_core.h @@ -58,7 +58,7 @@ typedef struct { void displayio_display_core_construct(displayio_display_core_t* self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte); + 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); bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c new file mode 100644 index 0000000000..967316c21d --- /dev/null +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -0,0 +1,339 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/display_core.h" +#include "supervisor/shared/display.h" +#include "supervisor/shared/tick.h" +#include "supervisor/usb.h" + +#include +#include + +#include "tick.h" + +void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, + mp_obj_t framebuffer, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, + uint16_t rotation, 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, + const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, + bool auto_refresh, uint16_t native_frames_per_second) { + // Turn off auto-refresh as we init. + self->auto_refresh = false; + self->framebuffer = framebuffer; + self->framebuffer_protocol = mp_proto_get_or_throw(MP_QSTR_protocol_framebuffer, framebuffer); + + uint16_t ram_width = 0x100; + uint16_t ram_height = 0x100; + + displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, colstart, rowstart, rotation, + color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); + + self->auto_brightness = auto_brightness; + self->first_manual_refresh = !auto_refresh; + + self->native_frames_per_second = native_frames_per_second; + self->native_ms_per_frame = 1000 / native_frames_per_second; + + 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)) { + pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + } else { + self->backlight_pwm.base.type = &pulseio_pwmout_type; + common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); + } + } + if (!self->auto_brightness && (self->framebuffer_protocol->set_brightness != NULL || self->backlight_inout.base.type != &mp_type_NoneType)) { + common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); + } else { + self->current_brightness = -1.0; + } + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + common_hal_framebufferio_framebufferdisplay_show(self, &circuitpython_splash); + self->auto_refresh = auto_refresh; +} + +bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, displayio_group_t* root_group) { + return displayio_display_core_show(&self->core, root_group); +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_width(framebufferio_framebufferdisplay_obj_t* self){ + return displayio_display_core_get_width(&self->core); +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_framebufferdisplay_obj_t* self){ + return displayio_display_core_get_height(&self->core); +} + +bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self) { + return self->auto_brightness; +} + +void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { + self->auto_brightness = auto_brightness; +} + +mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self) { + return self->current_brightness; +} + +bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness) { + self->updating_backlight = true; + bool ok = false; + if (self->framebuffer_protocol->set_brightness) { + self->framebuffer_protocol->set_brightness(self->framebuffer, brightness); + ok = true; + } else if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); + ok = true; + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); + ok = true; + } + self->updating_backlight = false; + if (ok) { + self->current_brightness = brightness; + } + return ok; +} + +mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t* self) { + return self->framebuffer; +} + +STATIC const displayio_area_t* _get_refresh_areas(framebufferio_framebufferdisplay_obj_t *self) { + if (self->core.full_refresh) { + self->core.area.next = NULL; + return &self->core.area; + } else if (self->core.current_group != NULL) { + return displayio_group_get_refresh_areas(self->core.current_group, NULL); + } + return NULL; +} + +STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area) { + uint16_t buffer_size = 128; // In uint32_ts + + displayio_area_t clipped; + // Clip the area to the display by overlapping the areas. If there is no overlap then we're done. + 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) { + rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped); + if (rows_per_buffer == 0) { + rows_per_buffer = 1; + } + // If pixels are packed by column then ensure rows_per_buffer is on a byte boundary. + if (self->core.colorspace.depth < 8 && !self->core.colorspace.pixels_in_byte_share_row) { + uint8_t pixels_per_byte = 8 / self->core.colorspace.depth; + if (rows_per_buffer % pixels_per_byte != 0) { + rows_per_buffer -= rows_per_buffer % pixels_per_byte; + } + } + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped); + buffer_size = pixels_per_buffer / pixels_per_word; + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + } + + // Allocated and shared as a uint32_t array so the compiler knows the + // alignment everywhere. + uint32_t buffer[buffer_size]; + uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + uint16_t remaining_rows = displayio_area_height(&clipped); + + for (uint16_t j = 0; j < subrectangles; j++) { + displayio_area_t subrectangle = { + .x1 = clipped.x1, + .y1 = clipped.y1 + rows_per_buffer * j, + .x2 = clipped.x2, + .y2 = clipped.y1 + rows_per_buffer * (j + 1) + }; + if (remaining_rows < rows_per_buffer) { + subrectangle.y2 = subrectangle.y1 + remaining_rows; + } + remaining_rows -= rows_per_buffer; + + memset(mask, 0, mask_length * sizeof(mask[0])); + memset(buffer, 0, buffer_size * sizeof(buffer[0])); + + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + + // COULDDO: this arithmetic only supports multiple-of-8 bpp + uint8_t *dest = self->bufinfo.buf + (subrectangle.y1 * self->core.width + subrectangle.x1) * (self->core.colorspace.depth / 8); + uint8_t *src = (uint8_t*)buffer; + size_t rowsize = (subrectangle.x2 - subrectangle.x1) * (self->core.colorspace.depth / 8); + size_t rowstride = self->core.width * (self->core.colorspace.depth/8); + for (uint16_t i = subrectangle.y1; i < subrectangle.y2; i++) { + memcpy(dest, src, rowsize); + dest += rowstride; + src += rowsize; + } + + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); + } + return true; +} + +STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t* self) { + displayio_display_core_start_refresh(&self->core); + self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); + const displayio_area_t* current_area = _get_refresh_areas(self); + while (current_area != NULL) { + _refresh_area(self, current_area); + current_area = current_area->next; + } + displayio_display_core_finish_refresh(&self->core); + self->framebuffer_protocol->swapbuffers(self->framebuffer); +} + +void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation){ + bool transposed = (self->core.rotation == 90 || self->core.rotation == 270); + bool will_transposed = (rotation == 90 || rotation == 270); + if(transposed != will_transposed) { + int tmp = self->core.width; + self->core.width = self->core.height; + 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->core.current_group != NULL) { + displayio_group_update_transform(self->core.current_group, &self->core.transform); + } +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_framebufferdisplay_obj_t* self){ + return self->core.rotation; +} + + +bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { + if (!self->auto_refresh && !self->first_manual_refresh) { + uint64_t current_time = supervisor_ticks_ms64(); + uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; + // Test to see if the real frame time is below our minimum. + if (current_ms_since_real_refresh > maximum_ms_per_real_frame) { + mp_raise_RuntimeError(translate("Below minimum frame rate")); + } + uint32_t current_ms_since_last_call = current_time - self->last_refresh_call; + self->last_refresh_call = current_time; + // Skip the actual refresh to help catch up. + if (current_ms_since_last_call > target_ms_per_frame) { + return false; + } + uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame); + // We're ahead of the game so wait until we align with the frame rate. + while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) { + RUN_BACKGROUND_TASKS; + } + } + self->first_manual_refresh = false; + _refresh_display(self); + return true; +} + +bool common_hal_framebufferio_framebufferdisplay_get_auto_refresh(framebufferio_framebufferdisplay_obj_t* self) { + return self->auto_refresh; +} + +void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_framebufferdisplay_obj_t* self, + bool auto_refresh) { + self->first_manual_refresh = !auto_refresh; + self->auto_refresh = auto_refresh; +} + +STATIC void _update_backlight(framebufferio_framebufferdisplay_obj_t* self) { + if (!self->auto_brightness || self->updating_backlight) { + return; + } + if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) { + return; + } + // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target + // should account for ambient light when possible. + common_hal_framebufferio_framebufferdisplay_set_brightness(self, 1.0); + + self->last_backlight_refresh = supervisor_ticks_ms64(); +} + +void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self) { + _update_backlight(self); + + if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) { + _refresh_display(self); + } +} + +void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { + release_display_core(&self->core); + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); + common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } + self->framebuffer_protocol->deinit(self->framebuffer); +} + +void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { + self->auto_refresh = true; + self->auto_brightness = 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); +} diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h new file mode 100644 index 0000000000..a5c8607bbc --- /dev/null +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H + +#include "py/obj.h" +#include "py/proto.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/display_core.h" + +typedef struct { + mp_obj_base_t base; + displayio_display_core_t core; + union { + digitalio_digitalinout_obj_t backlight_inout; + pulseio_pwmout_obj_t backlight_pwm; + }; + mp_obj_t framebuffer; + const struct _framebuffer_p_t *framebuffer_protocol; + mp_buffer_info_t bufinfo; + uint64_t last_backlight_refresh; + uint64_t last_refresh_call; + mp_float_t current_brightness; + uint16_t native_frames_per_second; + uint16_t native_ms_per_frame; + bool auto_refresh; + bool first_manual_refresh; + bool auto_brightness; + bool updating_backlight; +} framebufferio_framebufferdisplay_obj_t; + +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_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self); + +mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t* self); + +typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo); +typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t); +typedef void (*framebuffer_deinit_fun)(mp_obj_t); +typedef void (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); + +typedef struct _framebuffer_p_t { + MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer + framebuffer_get_bufinfo_fun get_bufinfo; + framebuffer_swapbuffers_fun swapbuffers; + framebuffer_deinit_fun deinit; + framebuffer_set_brightness_fun set_brightness; +} framebuffer_p_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-module/framebufferio/__init__.c b/shared-module/framebufferio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/framebufferio/__init__.h b/shared-module/framebufferio/__init__.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/convert_release_notes.py b/tools/convert_release_notes.py index 87b7e444b7..6491841029 100644 --- a/tools/convert_release_notes.py +++ b/tools/convert_release_notes.py @@ -52,6 +52,9 @@ class AdafruitBBCodeRenderer: def double_emphasis(self, text): return "[b]{}[/b]".format(text) + def emphasis(self, text): + return "[b]{}[/b]".format(text) + bbcode = mistune.Markdown(renderer=AdafruitBBCodeRenderer()) print() From 1d8a073c05c36133e02d839ed187b9d7abf24d79 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 11:57:52 -0500 Subject: [PATCH 17/42] nrf: protomatter port --- lib/protomatter | 2 +- .../nrf/common-hal/_protomatter/Protomatter.c | 66 +++++++++++++++++++ .../nrf/common-hal/_protomatter/Protomatter.h | 35 ++++++++++ ports/nrf/common-hal/_protomatter/__init__.c | 0 ports/nrf/common-hal/microcontroller/Pin.c | 12 ++++ ports/nrf/common-hal/pulseio/PulseOut.c | 5 +- ports/nrf/mpconfigport.mk | 3 + ports/nrf/peripherals/nrf/timers.c | 55 ++++++++++++++-- ports/nrf/peripherals/nrf/timers.h | 5 ++ 9 files changed, 171 insertions(+), 12 deletions(-) create mode 100644 ports/nrf/common-hal/_protomatter/Protomatter.c create mode 100644 ports/nrf/common-hal/_protomatter/Protomatter.h create mode 100644 ports/nrf/common-hal/_protomatter/__init__.c diff --git a/lib/protomatter b/lib/protomatter index c3a3e35731..c411714cbd 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit c3a3e35731d641cb5a21ae7319634afc419f5afe +Subproject commit c411714cbdc05725e80398acb18c3c1fb6fa68a4 diff --git a/ports/nrf/common-hal/_protomatter/Protomatter.c b/ports/nrf/common-hal/_protomatter/Protomatter.c new file mode 100644 index 0000000000..b6e55bbd4c --- /dev/null +++ b/ports/nrf/common-hal/_protomatter/Protomatter.c @@ -0,0 +1,66 @@ +/* + * This file is part of the Micro Python 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 "common-hal/_protomatter/Protomatter.h" + +#include "peripherals/nrf/timers.h" + +extern void _PM_IRQ_HANDLER(void); + +void *common_hal_protomatter_timer_allocate() { + nrfx_timer_t *timer = nrf_peripherals_allocate_timer_or_throw(); + nrf_peripherals_timer_never_reset(timer); + return timer->p_reg; +} + + +static void protomatter_event_handler(nrf_timer_event_t event_type, void *p_context) { + _PM_IRQ_HANDLER(); +} + +void common_hal_protomatter_timer_enable(void* ptr) { + nrfx_timer_t *timer = nrf_peripherals_timer_from_reg(ptr); + static const nrfx_timer_config_t timer_config = { + .frequency = NRF_TIMER_FREQ_16MHz, + .mode = NRF_TIMER_MODE_TIMER, + .bit_width = NRF_TIMER_BIT_WIDTH_16, + .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, + .p_context = NULL, + }; + nrfx_timer_init(timer, &timer_config, &protomatter_event_handler); +} + +void common_hal_protomatter_timer_disable(void* ptr) { + nrfx_timer_t *timer = nrf_peripherals_timer_from_reg(ptr); + nrfx_timer_uninit(timer); +} + +void common_hal_protomatter_timer_free(void* ptr) { + nrfx_timer_t *timer = nrf_peripherals_timer_from_reg(ptr); + nrf_peripherals_free_timer(timer); +} diff --git a/ports/nrf/common-hal/_protomatter/Protomatter.h b/ports/nrf/common-hal/_protomatter/Protomatter.h new file mode 100644 index 0000000000..8185bed0e5 --- /dev/null +++ b/ports/nrf/common-hal/_protomatter/Protomatter.h @@ -0,0 +1,35 @@ +/* + * This file is part of the Micro Python 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. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H + +void *common_hal_protomatter_timer_allocate(void); +void common_hal_protomatter_timer_enable(void*); +void common_hal_protomatter_timer_disable(void*); +void common_hal_protomatter_timer_free(void*); + +#endif diff --git a/ports/nrf/common-hal/_protomatter/__init__.c b/ports/nrf/common-hal/_protomatter/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index b7931a2e16..3132c76318 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -196,3 +196,15 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { return pin_number_is_free(pin->number); } + +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) { + return pin->number; +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) { + claim_pin(pin); +} + +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no); +} diff --git a/ports/nrf/common-hal/pulseio/PulseOut.c b/ports/nrf/common-hal/pulseio/PulseOut.c index d0433247ac..270cb45d6d 100644 --- a/ports/nrf/common-hal/pulseio/PulseOut.c +++ b/ports/nrf/common-hal/pulseio/PulseOut.c @@ -102,10 +102,7 @@ void pulseout_reset() { void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) { if (refcount == 0) { - timer = nrf_peripherals_allocate_timer(); - if (timer == NULL) { - mp_raise_RuntimeError(translate("All timers in use")); - } + timer = nrf_peripherals_allocate_timer_or_throw(); } refcount++; diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index fcc59c484a..5ca1f0f35b 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -51,6 +51,9 @@ endif # frequencyio not yet implemented CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_PROTOMATTER = 1 +CIRCUITPY_FRAMEBUFFERIO = 1 + # nRF52840-specific ifeq ($(MCU_CHIP),nrf52840) diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c index 88f3dd4681..fd814968dc 100644 --- a/ports/nrf/peripherals/nrf/timers.c +++ b/ports/nrf/peripherals/nrf/timers.c @@ -25,6 +25,7 @@ */ #include "common-hal/pulseio/PulseOut.h" +#include "peripherals/nrf/timers.h" #include @@ -54,14 +55,47 @@ STATIC nrfx_timer_t nrfx_timers[] = { }; static bool nrfx_timer_allocated[ARRAY_SIZE(nrfx_timers)]; +static bool nrfx_timer_never_reset[ARRAY_SIZE(nrfx_timers)]; void timers_reset(void) { for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (nrfx_timer_never_reset[i]) { + continue; + } nrfx_timer_uninit(&nrfx_timers[i]); nrfx_timer_allocated[i] = false; } } +void nrf_peripherals_timer_never_reset(nrfx_timer_t* timer) { + int idx = nrf_peripherals_timer_idx_from_timer(timer); + nrfx_timer_never_reset[idx] = true; +} + +void nrf_peripherals_timer_reset_ok(nrfx_timer_t* timer) { + int idx = nrf_peripherals_timer_idx_from_timer(timer); + nrfx_timer_never_reset[idx] = false; +} + +nrfx_timer_t* nrf_peripherals_timer_from_reg(NRF_TIMER_Type* ptr) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (nrfx_timers[i].p_reg == ptr) { + return &nrfx_timers[i]; + } + } + return NULL; +} + +size_t nrf_peripherals_timer_idx_from_timer(nrfx_timer_t* ptr) { + for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { + if (&nrfx_timers[i] == ptr) { + return i; + } + } + return ~(size_t)0; +} + + // Returns a free nrfx_timer instance, and marks it as allocated. // The caller should init as with the desired config. // Returns NULL if no timer is available. @@ -75,14 +109,21 @@ nrfx_timer_t* nrf_peripherals_allocate_timer(void) { return NULL; } +nrfx_timer_t* nrf_peripherals_allocate_timer_or_throw(void) { + nrfx_timer_t* result = nrf_peripherals_allocate_timer(); + if (!result) { + mp_raise_RuntimeError(translate("All timers in use")); + } + return result; +} + // Free a timer, which may or may not have been initialized. void nrf_peripherals_free_timer(nrfx_timer_t* timer) { - for (size_t i = 0; i < ARRAY_SIZE(nrfx_timers); i ++) { - if (timer == &nrfx_timers[i]) { - nrfx_timer_allocated[i] = false; - // Safe to call even if not initialized. - nrfx_timer_uninit(timer); - return; - } + size_t idx = nrf_peripherals_timer_idx_from_timer(timer); + if (idx != ~(size_t)0) { + nrfx_timer_allocated[idx] = false; + nrfx_timer_never_reset[idx] = false; + // Safe to call even if not initialized. + nrfx_timer_uninit(timer); } } diff --git a/ports/nrf/peripherals/nrf/timers.h b/ports/nrf/peripherals/nrf/timers.h index 7d3815579a..cf96c6273b 100644 --- a/ports/nrf/peripherals/nrf/timers.h +++ b/ports/nrf/peripherals/nrf/timers.h @@ -29,4 +29,9 @@ void timers_reset(void); nrfx_timer_t* nrf_peripherals_allocate_timer(void); +nrfx_timer_t* nrf_peripherals_allocate_timer_or_throw(void); void nrf_peripherals_free_timer(nrfx_timer_t* timer); +void nrf_peripherals_timer_never_reset(nrfx_timer_t* timer); +void nrf_peripherals_timer_reset_ok(nrfx_timer_t* timer); +nrfx_timer_t* nrf_peripherals_timer_from_reg(NRF_TIMER_Type* ptr); +size_t nrf_peripherals_timer_idx_from_timer(nrfx_timer_t* ptr); From 3a94412cd35c39bf30f29cb2b79be3870709c809 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 11:59:15 -0500 Subject: [PATCH 18/42] protomatter: more memory allocation fixes - bump supervisor alloc count by 4 (we actually use 5) - move reconstruct to after gc heap is reset - destroy protomatter object entirely if not used by a FramebufferDisplay - ensure previous supervisor allocations are released - zero out pointers so GC can collect them --- shared-module/_protomatter/Protomatter.c | 6 ++++++ shared-module/_protomatter/allocator.h | 4 +--- shared-module/displayio/__init__.c | 16 +++++++++++++++- supervisor/shared/display.c | 9 +++++++++ supervisor/shared/memory.c | 2 +- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index cbb60db6d3..bec9586f86 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -78,6 +78,11 @@ void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_ // 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->core.rgbPins); + _PM_FREE(self->core.addr); + _PM_FREE(self->core.screenData); + self->framebuffer = NULL; self->bufinfo.buf = _PM_allocator_impl(self->bufsize); self->bufinfo.len = self->bufsize; @@ -156,6 +161,7 @@ void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t* se if (self->core.rgbPins) { _PM_free(&self->core); } + memset(&self->core, 0, sizeof(self->core)); self->base.type = NULL; } diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 8d9d7ff960..9b7590df35 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -6,7 +6,7 @@ #include "supervisor/memory.h" #define _PM_ALLOCATOR _PM_allocator_impl -#define _PM_FREE _PM_free_impl +#define _PM_FREE(x) (_PM_free_impl((x)), (x)=NULL, (void)0) static inline void *_PM_allocator_impl(size_t sz) { supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); @@ -22,8 +22,6 @@ static inline void _PM_free_impl(void *ptr_in) { if (allocation) { free_memory(allocation); - } else { - m_free(ptr_in); } } diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 225aa2008e..dfa3e74737 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -21,6 +21,18 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display; + if (display->framebuffer == pm) { + return true; + } + } + } + return false; +} + // Check for recursive calls to displayio_background. bool displayio_background_in_progress = false; @@ -152,7 +164,9 @@ void reset_displays(void) { #if CIRCUITPY_PROTOMATTER } else if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { protomatter_protomatter_obj_t * pm = &displays[i].protomatter; - common_hal_protomatter_protomatter_reconstruct(pm, NULL); + if(!any_display_uses_this_protomatter(pm)) { + common_hal_protomatter_protomatter_deinit(pm); + } #endif } else { // Not an active display bus. diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 855432d645..050ba6e196 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -29,6 +29,7 @@ #include #include "py/mpstate.h" +#include "shared-module/displayio/__init__.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" @@ -112,6 +113,14 @@ void supervisor_display_move_memory(void) { grid->inline_tiles = false; } MP_STATE_VM(terminal_tilegrid_tiles) = NULL; + #if CIRCUITPY_PROTOMATTER + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_obj_t * pm = &displays[i].protomatter; + common_hal_protomatter_protomatter_reconstruct(pm, NULL); + } + } + #endif #endif } diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 51037bd6d8..d52334eb49 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -31,7 +31,7 @@ #include "supervisor/shared/display.h" -#define CIRCUITPY_SUPERVISOR_ALLOC_COUNT 8 +#define CIRCUITPY_SUPERVISOR_ALLOC_COUNT (12) static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; // We use uint32_t* to ensure word (4 byte) alignment. From 1f3821220e396721ab83127f0965032639d613ba Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 16:10:19 -0500 Subject: [PATCH 19/42] fix build for non-displayio & non-protomatter targets --- shared-module/displayio/__init__.c | 2 ++ supervisor/shared/display.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dfa3e74737..21cbfa83ae 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -21,6 +21,7 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +#if CIRCUITPY_PROTOMATTER STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { @@ -32,6 +33,7 @@ STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) } return false; } +#endif // Check for recursive calls to displayio_background. bool displayio_background_in_progress = false; diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 050ba6e196..cdf710d268 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -29,12 +29,15 @@ #include #include "py/mpstate.h" -#include "shared-module/displayio/__init__.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" #include "supervisor/memory.h" +#if CIRCUITPY_PROTOMATTER +#include "shared-module/displayio/__init__.h" +#endif + extern size_t blinka_bitmap_data[]; extern displayio_bitmap_t blinka_bitmap; extern displayio_group_t circuitpython_splash; From 759fdffda51811f333772e8746aed45e15e6565f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 20:08:01 -0500 Subject: [PATCH 20/42] Update ports/atmel-samd/boards/pyportal_titano/board.c Co-Authored-By: Scott Shawcroft --- ports/atmel-samd/boards/pyportal_titano/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c index 40b7e84025..e7763b6e5c 100644 --- a/ports/atmel-samd/boards/pyportal_titano/board.c +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -101,7 +101,7 @@ void board_init(void) { 0, // rotation 16, // Color depth false, // grayscale - false, // pixels_i|n_byte_share_row (unused for depths > 8) + false, // pixels_in_byte_share_row (unused for depths > 8) 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 true, // reverse_pixels_in_word From 89eb45a13c48509a18ecadaacd983e880e17aa9c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 2 Apr 2020 14:22:08 -0500 Subject: [PATCH 21/42] use floor division in docstring Co-Authored-By: Scott Shawcroft --- shared-bindings/_protomatter/Protomatter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 8d0d223bb5..cb3ed7c4f3 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -80,7 +80,7 @@ STATIC void claim_pins_nr(mp_obj_t seq) { //| //| Create a Protomatter object with the given attributes. The height of //| the display is determined by the number of rgb and address pins: -//| len(rgb_pins)/3 * 2 ** len(address_pins). With 6 RGB pins and 4 +//| len(rgb_pins) // 3 * 2 ** len(address_pins). With 6 RGB pins and 4 //| address lines, the display will be 32 pixels tall. //| //| Up to 30 RGB pins and 8 address pins are supported. From 5fcba97a5185bd69c2213b38f6c8fc580dafde23 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:50:12 -0500 Subject: [PATCH 22/42] Make function name more descriptive --- shared-bindings/_protomatter/Protomatter.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index cb3ed7c4f3..3c790ff7da 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -62,15 +62,15 @@ STATIC void validate_pins(qstr what, uint8_t* pin_nos, mp_int_t max_pins, mp_obj } } -STATIC void claim_pin_nr(mp_obj_t pin) { +STATIC void claim_and_never_reset_pin(mp_obj_t pin) { common_hal_mcu_pin_claim(pin); common_hal_never_reset_pin(pin); } -STATIC void claim_pins_nr(mp_obj_t seq) { +STATIC void claim_and_never_reset_pins(mp_obj_t seq) { mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); for (mp_int_t i=0; i Date: Fri, 3 Apr 2020 10:55:14 -0500 Subject: [PATCH 23/42] deinit: Work harder to ensure storage is released at deinit --- shared-module/_protomatter/Protomatter.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index bec9586f86..59dac3e6d1 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -163,7 +163,14 @@ void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t* se } memset(&self->core, 0, sizeof(self->core)); + // 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); self->base.type = NULL; + + // If a framebuffer was passed in to the constructor, NULL the reference + // here so that it will become GC'able + self->framebuffer = NULL; } void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { From a663a7dd30d2cfed78644dcaa6e5ef25566acd82 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:52:50 -0500 Subject: [PATCH 24/42] _protomatter: move get/set paused into shared-module --- shared-bindings/_protomatter/Protomatter.c | 11 +++-------- shared-bindings/_protomatter/Protomatter.h | 2 ++ shared-module/_protomatter/Protomatter.c | 12 ++++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 3c790ff7da..b7b28630dc 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -193,7 +193,7 @@ static void check_for_deinit(protomatter_protomatter_obj_t *self) { STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - return mp_obj_new_bool(self->paused); + return mp_obj_new_bool(common_hal_protomatter_protomatter_get_paused(self)); } MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); @@ -201,12 +201,7 @@ STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t va protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); bool paused = mp_obj_is_true(value_in); - if (paused && !self->paused) { - _PM_stop(&self->core); - } else if (!paused && self->paused) { - _PM_resume(&self->core); - } - self->paused = paused; + common_hal_protomatter_protomatter_set_paused(self, paused); return mp_const_none; } @@ -262,7 +257,7 @@ STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { } STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { - protomatter_protomatter_set_paused(self_in, mp_obj_new_bool(value <= 0)); + common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); } STATIC const framebuffer_p_t protomatter_protomatter_proto = { diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h index cacc39a304..0a52c556fc 100644 --- a/shared-bindings/_protomatter/Protomatter.h +++ b/shared-bindings/_protomatter/Protomatter.h @@ -52,5 +52,7 @@ void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t* void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t*); void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); +void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused); +bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self); #endif diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index 59dac3e6d1..9f67bfad31 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -180,3 +180,15 @@ void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { gc_collect_ptr(self->core.screenData); } +void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused) { + if (paused && !self->paused) { + _PM_stop(&self->core); + } else if (!paused && self->paused) { + _PM_resume(&self->core); + } + self->paused = paused; +} + +bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self) { + return self->paused; +} From 50219862e13f60aadb0515a01131d7909bb07def Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:54:15 -0500 Subject: [PATCH 25/42] protomatter: make docstring match implementation --- shared-bindings/_protomatter/Protomatter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index b7b28630dc..d5f9aa1aed 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -214,7 +214,7 @@ const mp_obj_property_t protomatter_protomatter_paused_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. method:: write(buf) +//| .. method:: swapbuffers() //| //| Transmits the color data in the buffer to the pixels so that they are shown. //| From baf04b7738bdcf234eecad9e03904c1cadc44f50 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:59:06 -0500 Subject: [PATCH 26/42] FramebufferDisplay: remove probably not needed constructor arguments --- .../framebufferio/FramebufferDisplay.c | 25 +++---------------- .../framebufferio/FramebufferDisplay.h | 5 ++-- .../framebufferio/FramebufferDisplay.c | 10 ++++---- 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 9f1df8bfaa..9b761dd2d2 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -54,20 +54,12 @@ //| //| :param framebuffer: The framebuffer that the display is connected to //| :type framebuffer: any core object implementing the framebuffer protocol -//| :param callback: Function or bound method to call when the framebuffer has been updated. The callback receives one argument, the framebuffer object. //| :param int width: Width in pixels //| :param int height: Height in pixels -//| :param int colstart: The index if the first visible column -//| :param int rowstart: The index if the first visible row //| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) //| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays //| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) -//| :param bool grayscale: True if the display only shows a single color. -//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. //| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. -//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) -//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) -//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 //| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight //| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True. //| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. @@ -75,20 +67,14 @@ //| :param int native_frames_per_second: Number of display refreshes per second //| STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + enum { ARG_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, - { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, - { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, - { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, @@ -117,12 +103,9 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t self, framebuffer, args[ARG_width].u_int, args[ARG_height].u_int, - args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, - args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, - args[ARG_pixels_in_byte_share_row].u_bool, - args[ARG_bytes_per_cell].u_bool, - args[ARG_reverse_pixels_in_byte].u_bool, - args[ARG_reverse_bytes_in_word].u_bool, + rotation, + args[ARG_color_depth].u_int, + args[ARG_bytes_per_cell].u_int, MP_OBJ_TO_PTR(backlight_pin), brightness, args[ARG_auto_brightness].u_bool, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index af0bd2c415..b63439e0c4 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -40,9 +40,8 @@ extern const mp_obj_type_t framebufferio_framebufferdisplay_type; void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, mp_obj_t framebuffer, uint16_t width, uint16_t height, - int16_t colstart, int16_t rowstart, - uint16_t rotation, 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, + uint16_t rotation, uint16_t color_depth, + uint8_t bytes_per_cell, const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index 967316c21d..ec2fe7b314 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -42,9 +42,9 @@ #include "tick.h" void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, - mp_obj_t framebuffer, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, - uint16_t rotation, 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, + mp_obj_t framebuffer, uint16_t width, uint16_t height, + uint16_t rotation, uint16_t color_depth, + uint8_t bytes_per_cell, const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second) { // Turn off auto-refresh as we init. @@ -55,8 +55,8 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu uint16_t ram_width = 0x100; uint16_t ram_height = 0x100; - displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, colstart, rowstart, rotation, - color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); + displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, 0, 0, rotation, + color_depth, false, false, bytes_per_cell, false, false); self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; From 23bced26da40d5d87b0aac18e6aac525d4d27bac Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 7 Apr 2020 11:18:57 -0500 Subject: [PATCH 27/42] samd: actually disable protomatter timer Just setting the timer handler to NO_INTERRUPT doesn't stop the interrupt from occurring. --- ports/atmel-samd/common-hal/_protomatter/Protomatter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/common-hal/_protomatter/Protomatter.c b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c index 702de0e3d4..bf9cafb6b9 100644 --- a/ports/atmel-samd/common-hal/_protomatter/Protomatter.c +++ b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c @@ -64,6 +64,7 @@ void common_hal_protomatter_timer_disable(void* ptr) { return; } set_timer_handler(true, timer_index, TC_HANDLER_NO_INTERRUPT); + tc_set_enable(ptr, false); } void common_hal_protomatter_timer_free(void* ptr) { From 0ca270172f36817c14790eb87053e3c326001822 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 7 Apr 2020 11:19:24 -0500 Subject: [PATCH 28/42] protomatter: allocator: Never supervisor-alloc while gc available This may have been contributing to fragmentation of the supervisor heap --- shared-module/_protomatter/allocator.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 9b7590df35..501a26098f 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -2,6 +2,7 @@ #define MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H #include +#include "py/gc.h" #include "py/misc.h" #include "supervisor/memory.h" @@ -9,11 +10,11 @@ #define _PM_FREE(x) (_PM_free_impl((x)), (x)=NULL, (void)0) static inline void *_PM_allocator_impl(size_t sz) { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); - if (allocation) { - return allocation->ptr; - } else { + if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); + } else { + supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + return allocation ? allocation->ptr : NULL; } } From 5dae23c0e787e38ea737f8333a1ad85a1de5184d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 7 Apr 2020 11:19:47 -0500 Subject: [PATCH 29/42] protomatter: release the protomatter object during release_displays() --- shared-module/displayio/__init__.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 21cbfa83ae..cf1bc45d9d 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -102,6 +102,10 @@ 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 + } else if (bus_type == &protomatter_Protomatter_type) { + common_hal_protomatter_protomatter_deinit(&displays[i].protomatter); +#endif } displays[i].fourwire_bus.base.type = &mp_type_NoneType; } From b1fab1cdac6a3e878a7d7a654f6ea6f92f60cc88 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 9 Apr 2020 09:10:09 -0500 Subject: [PATCH 30/42] Make stripping circuitpython optional, not the default --- py/mkrules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index 292d257465..13a73b90e6 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -145,7 +145,7 @@ $(PROG): $(OBJ) # Do not pass COPT here - it's *C* compiler optimizations. For example, # we may want to compile using Thumb, but link with non-Thumb libc. $(Q)$(CC) -o $@ $^ $(LIB) $(LDFLAGS) -ifndef DEBUG +ifdef STRIP_CIRCUITPYTHON $(Q)$(STRIP) $(STRIPFLAGS_EXTRA) $(PROG) endif $(Q)$(SIZE) $$(find $(BUILD) -path "$(BUILD)/build/frozen*.o") $(PROG) From 9019710a1e75d4042d37dd3285d06e3f24aec449 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 9 Apr 2020 09:11:37 -0500 Subject: [PATCH 31/42] protomatter: improve an error message --- shared-bindings/_protomatter/Protomatter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index d5f9aa1aed..f3de6a86e0 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -54,7 +54,7 @@ STATIC uint8_t validate_pin(mp_obj_t obj) { STATIC void validate_pins(qstr what, uint8_t* pin_nos, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out) { mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); if (len > max_pins) { - mp_raise_ValueError_varg(translate("At most %d %q may be specified"), max_pins, what); + mp_raise_ValueError_varg(translate("At most %d %q may be specified (not %d)"), max_pins, what, len); } *count_out = len; for (mp_int_t i=0; i Date: Thu, 9 Apr 2020 09:11:55 -0500 Subject: [PATCH 32/42] protomatter: Use low end of supervisor heap Per @tannewt, this area "sees more churn", so it's probably the right choice here --- shared-module/_protomatter/allocator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 501a26098f..1ae127de21 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -13,7 +13,7 @@ static inline void *_PM_allocator_impl(size_t sz) { if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); } else { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); return allocation ? allocation->ptr : NULL; } } From 4a05e938ed8bd33f0ec3204d988fa6948e1e11d2 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Apr 2020 08:45:37 -0500 Subject: [PATCH 33/42] protomatter: validate pins to give better error message The numbered error from the underlying library is not helpful for beginning users --- shared-bindings/_protomatter/Protomatter.c | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index f3de6a86e0..88974e658e 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -74,6 +74,65 @@ STATIC void claim_and_never_reset_pins(mp_obj_t seq) { } } +STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_t rgb_pin_count, bool allow_inefficient) { + uint32_t port = clock_pin / 32; + uint32_t bit_mask = 1 << (clock_pin % 32); + + for (uint8_t i = 0; i < rgb_pin_count; i++) { + uint32_t pin_port = rgb_pins[i] / 32; + + if (pin_port != port) { + mp_raise_ValueError_varg( + translate("rgb_pins[%d] is not on the same port as clock"), i); + } + + uint32_t pin_mask = 1 << (rgb_pins[i] % 32); + if (pin_mask & bit_mask) { + mp_raise_ValueError_varg( + translate("rgb_pins[%d] duplicates another pin assignment"), i); + } + + bit_mask |= pin_mask; + } + + if (allow_inefficient) { + return; + } + + uint8_t byte_mask = 0; + if (bit_mask & 0x000000FF) byte_mask |= 0b0001; + if (bit_mask & 0x0000FF00) byte_mask |= 0b0010; + if (bit_mask & 0x00FF0000) byte_mask |= 0b0100; + if (bit_mask & 0xFF000000) byte_mask |= 0b1000; + + uint8_t bytes_per_element = 0xff; + uint8_t ideal_bytes_per_element = (rgb_pin_count + 7) / 8; + + switch(byte_mask) { + case 0b0001: + case 0b0010: + case 0b0100: + case 0b1000: + bytes_per_element = 1; + break; + + case 0b0011: + case 0b1100: + bytes_per_element = 2; + break; + + default: + bytes_per_element = 4; + break; + } + + if (bytes_per_element != ideal_bytes_per_element) { + mp_raise_ValueError_varg( + translate("Pinout uses %d bytes per element, which consumes more than the ideal %d bytes. If this cannot be avoided, pass allow_inefficient=True to the constructor"), + bytes_per_element, ideal_bytes_per_element); + } +} + //| :class:`~_protomatter.Protomatter` displays an in-memory framebuffer to an LED matrix. //| //| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, oe_pin, *, doublebuffer=True, framebuffer=None) @@ -141,6 +200,8 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); + preflight_pins_or_throw(clock_pin, rgb_pins, rgb_count, true); + mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; if (framebuffer == mp_const_none) { int width = args[ARG_width].u_int; From 129c6369cfd510b12e5f8ae1d9c9a51853f1b498 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Apr 2020 08:45:42 -0500 Subject: [PATCH 34/42] protomatter: code style --- shared-bindings/_protomatter/Protomatter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 88974e658e..f6ac191889 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -332,7 +332,7 @@ STATIC const framebuffer_p_t protomatter_protomatter_proto = { STATIC mp_int_t protomatter_protomatter_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_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)) { + if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { return 1; } *bufinfo = self->bufinfo; From ba20bc8b4322373ec9ed55ed9f299675ea2801f8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Apr 2020 09:07:06 -0500 Subject: [PATCH 35/42] framebufferio: move backlight down to the underlying framebuffer --- shared-bindings/_protomatter/Protomatter.c | 3 +- .../framebufferio/FramebufferDisplay.c | 17 ++--- .../framebufferio/FramebufferDisplay.h | 3 +- .../framebufferio/FramebufferDisplay.c | 65 ++++--------------- .../framebufferio/FramebufferDisplay.h | 15 ++--- 5 files changed, 28 insertions(+), 75 deletions(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index f6ac191889..50480004cc 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -317,8 +317,9 @@ STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { protomatter_protomatter_deinit(self_in); } -STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { +STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); + return true; } STATIC const framebuffer_p_t protomatter_protomatter_proto = { diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 9b761dd2d2..538d3afb46 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -67,7 +67,7 @@ //| :param int native_frames_per_second: Number of display refreshes per second //| STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + enum { ARG_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, @@ -75,9 +75,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, - { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, - { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, }; @@ -87,10 +84,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; - const mcu_pin_obj_t* backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); - - mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); - mp_int_t rotation = args[ARG_rotation].u_int; if (rotation % 90 != 0) { mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); @@ -106,9 +99,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t rotation, args[ARG_color_depth].u_int, args[ARG_bytes_per_cell].u_int, - MP_OBJ_TO_PTR(backlight_pin), - brightness, - args[ARG_auto_brightness].u_bool, args[ARG_auto_refresh].u_bool, args[ARG_native_frames_per_second].u_int ); @@ -260,7 +250,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_brightness_o STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); - common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + bool ok = common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } return mp_const_none; } diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index b63439e0c4..56ef8abc47 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -42,7 +42,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu mp_obj_t framebuffer, uint16_t width, uint16_t height, uint16_t rotation, uint16_t color_depth, uint8_t bytes_per_cell, - const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second); bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, @@ -59,7 +58,7 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_ void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation); bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); -void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); +bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index ec2fe7b314..bd0764e8e4 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -45,7 +45,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu mp_obj_t framebuffer, uint16_t width, uint16_t height, uint16_t rotation, uint16_t color_depth, uint8_t bytes_per_cell, - const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second) { // Turn off auto-refresh as we init. self->auto_refresh = false; @@ -58,7 +57,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, 0, 0, rotation, color_depth, false, false, bytes_per_cell, false, false); - self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; self->native_frames_per_second = native_frames_per_second; @@ -66,25 +64,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu 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)) { - pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); - if (result != PWMOUT_OK) { - self->backlight_inout.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); - common_hal_never_reset_pin(backlight_pin); - } else { - self->backlight_pwm.base.type = &pulseio_pwmout_type; - common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); - } - } - if (!self->auto_brightness && (self->framebuffer_protocol->set_brightness != NULL || self->backlight_inout.base.type != &mp_type_NoneType)) { - common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); - } else { - self->current_brightness = -1.0; - } - // Set the group after initialization otherwise we may send pixels while we delay in // initialization. common_hal_framebufferio_framebufferdisplay_show(self, &circuitpython_splash); @@ -104,33 +83,31 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_fr } bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self) { - return self->auto_brightness; + if (self->framebuffer_protocol->get_auto_brightness) { + return self->framebuffer_protocol->get_auto_brightness(self->framebuffer); + } + return true; } -void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { - self->auto_brightness = auto_brightness; +bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { + if (self->framebuffer_protocol->set_auto_brightness) { + return self->framebuffer_protocol->set_auto_brightness(self->framebuffer, auto_brightness); + } + return false; } mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self) { - return self->current_brightness; + if (self->framebuffer_protocol->set_brightness) { + return self->framebuffer_protocol->get_brightness(self->framebuffer); + } + return -1; } bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness) { - self->updating_backlight = true; bool ok = false; if (self->framebuffer_protocol->set_brightness) { self->framebuffer_protocol->set_brightness(self->framebuffer, brightness); ok = true; - } else if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); - ok = true; - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); - ok = true; - } - self->updating_backlight = false; - if (ok) { - self->current_brightness = brightness; } return ok; } @@ -295,17 +272,8 @@ void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_ } STATIC void _update_backlight(framebufferio_framebufferdisplay_obj_t* self) { - if (!self->auto_brightness || self->updating_backlight) { - return; - } - if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) { - return; - } // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target // should account for ambient light when possible. - common_hal_framebufferio_framebufferdisplay_set_brightness(self, 1.0); - - self->last_backlight_refresh = supervisor_ticks_ms64(); } void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self) { @@ -318,18 +286,11 @@ void framebufferio_framebufferdisplay_background(framebufferio_framebufferdispla void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { release_display_core(&self->core); - if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); - common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); - } self->framebuffer_protocol->deinit(self->framebuffer); } void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { self->auto_refresh = true; - self->auto_brightness = true; common_hal_framebufferio_framebufferdisplay_show(self, NULL); } diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h index a5c8607bbc..a7b91a522e 100644 --- a/shared-module/framebufferio/FramebufferDisplay.h +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -40,22 +40,15 @@ typedef struct { mp_obj_base_t base; displayio_display_core_t core; - union { - digitalio_digitalinout_obj_t backlight_inout; - pulseio_pwmout_obj_t backlight_pwm; - }; mp_obj_t framebuffer; const struct _framebuffer_p_t *framebuffer_protocol; mp_buffer_info_t bufinfo; uint64_t last_backlight_refresh; uint64_t last_refresh_call; - mp_float_t current_brightness; uint16_t native_frames_per_second; uint16_t native_ms_per_frame; bool auto_refresh; bool first_manual_refresh; - bool auto_brightness; - bool updating_backlight; } framebufferio_framebufferdisplay_obj_t; void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self); @@ -69,14 +62,20 @@ mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebuffer typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo); typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t); typedef void (*framebuffer_deinit_fun)(mp_obj_t); -typedef void (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); +typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); +typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t); +typedef bool (*framebuffer_set_auto_brightness_fun)(mp_obj_t, bool); +typedef bool (*framebuffer_get_auto_brightness_fun)(mp_obj_t); typedef struct _framebuffer_p_t { MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer framebuffer_get_bufinfo_fun get_bufinfo; framebuffer_swapbuffers_fun swapbuffers; framebuffer_deinit_fun deinit; + framebuffer_get_brightness_fun get_brightness; framebuffer_set_brightness_fun set_brightness; + framebuffer_get_auto_brightness_fun get_auto_brightness; + framebuffer_set_auto_brightness_fun set_auto_brightness; } framebuffer_p_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H From 5d328c3b449dbd0eaf40c2edc205fb7c5d381589 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Apr 2020 09:07:16 -0500 Subject: [PATCH 36/42] protomatter: clarify by comment why these functions exist --- shared-bindings/_protomatter/Protomatter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 50480004cc..3b3fdae8c9 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -309,10 +309,12 @@ STATIC void protomatter_protomatter_get_bufinfo(mp_obj_t self_in, mp_buffer_info *bufinfo = self->bufinfo; } +// This version exists so that the return value of the function can be none, matching the protocol STATIC void protomatter_protomatter_swapbuffers_void(mp_obj_t self_in) { protomatter_protomatter_swapbuffers(self_in); } +// This version exists so that the return value of the function can be none, matching the protocol STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { protomatter_protomatter_deinit(self_in); } From 880fff80e904ef4b173d551742b7acde56114f0c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 08:51:35 -0500 Subject: [PATCH 37/42] protomatter: Respond to review comments - rename oe_pin -> output_enable_pin - improve and reorganize docstrings - rename swapbuffers->refresh - rename "paused" -> "brightness", change semantics slightly - common_hal several functions - clarify why the common_hal routines can't be used directly in the protocol's function pointers - whitespace cleanups - remove prototypes for nonexistent functions --- shared-bindings/_protomatter/Protomatter.c | 108 ++++++++++-------- shared-bindings/_protomatter/Protomatter.h | 1 + .../framebufferio/FramebufferDisplay.c | 2 +- .../framebufferio/FramebufferDisplay.h | 3 - shared-module/_protomatter/Protomatter.c | 10 +- shared-module/_protomatter/allocator.h | 4 +- 6 files changed, 71 insertions(+), 57 deletions(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 3b3fdae8c9..cfc0ba6edf 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -135,7 +135,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| :class:`~_protomatter.Protomatter` displays an in-memory framebuffer to an LED matrix. //| -//| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, oe_pin, *, doublebuffer=True, framebuffer=None) +//| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, output_enable_pin, *, doublebuffer=True, framebuffer=None) //| //| Create a Protomatter object with the given attributes. The height of //| the display is determined by the number of rgb and address pins: @@ -153,12 +153,17 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| microcontroller board. For instance, the Feather M4 Express works //| together with the RGB Matrix Feather. //| -//| When specified as True, double buffering can reduce some flickering of -//| the matrix; however, this increases memory usage. +//| The framebuffer is in "RGB565" format. //| -//| The framebuffer is in "RGB565" format. If a framebuffer is not -//| passed in, one is allocated and initialized to all black. To update -//| the content, modify the framebuffer and call swapbuffers. +//| "RGB565" means that it is organized as a series of 16-bit numbers +//| where the highest 5 bits are interpreted as red, the next 6 as +//| green, and the final 5 as blue. The object can be any buffer, but +//| `array.array` and `ulab.array` objects are most often useful. +//| To update the content, modify the framebuffer and call refresh. +//| +//| If a framebuffer is not passed in, one is allocated and initialized +//| to all black. In any case, the framebuffer can be retrieved +//| by passing the protomatter object to memoryview(). //| //| If doublebuffer is False, some memory is saved, but the display may //| flicker during updates. @@ -166,10 +171,13 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| If a framebuffer is not passed in, one is allocated internally. To //| retrieve it, pass the protomatter object to memoryview(). //| +//| A Protomatter framebuffer is often used in conjunction with a +//| `framebufferio.FramebufferDisplay`. +//| STATIC mp_obj_t protomatter_protomatter_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_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list, - ARG_clock_pin, ARG_latch_pin, ARG_oe_pin, ARG_doublebuffer, ARG_framebuffer }; + ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer }; static const mp_arg_t allowed_args[] = { { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED }, { MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED }, @@ -177,7 +185,7 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size { MP_QSTR_addr_pins, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_clock_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_latch_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_oe_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_output_enable_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_doublebuffer, MP_ARG_BOOL, { .u_bool = true } }, { MP_QSTR_framebuffer, MP_ARG_OBJ, { .u_obj = mp_const_none } }, }; @@ -195,7 +203,7 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size uint8_t addr_pins[MP_ARRAY_SIZE(self->addr_pins)]; uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj); uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj); - uint8_t oe_pin = validate_pin(args[ARG_oe_pin].u_obj); + uint8_t output_enable_pin = validate_pin(args[ARG_output_enable_pin].u_obj); validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); @@ -214,14 +222,14 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size args[ARG_bit_depth].u_int, rgb_count, rgb_pins, addr_count, addr_pins, - clock_pin, latch_pin, oe_pin, + clock_pin, latch_pin, output_enable_pin, args[ARG_doublebuffer].u_bool, framebuffer, NULL); claim_and_never_reset_pins(args[ARG_rgb_list].u_obj); claim_and_never_reset_pins(args[ARG_addr_list].u_obj); claim_and_never_reset_pin(args[ARG_clock_pin].u_obj); - claim_and_never_reset_pin(args[ARG_oe_pin].u_obj); + claim_and_never_reset_pin(args[ARG_output_enable_pin].u_obj); claim_and_never_reset_pin(args[ARG_latch_pin].u_obj); return MP_OBJ_FROM_PTR(self); @@ -247,79 +255,80 @@ static void check_for_deinit(protomatter_protomatter_obj_t *self) { } } -//| .. attribute:: paused +//| .. attribute:: brightness //| -//| When paused, the matrix is not driven and all its LEDs are unlit. +//| In the current implementation, 0.0 turns the display off entirely +//| and any other value up to 1.0 turns the display on fully. //| -STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { +STATIC mp_obj_t protomatter_protomatter_get_brightness(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - return mp_obj_new_bool(common_hal_protomatter_protomatter_get_paused(self)); + return mp_obj_new_float(common_hal_protomatter_protomatter_get_paused(self)? 0.0f : 1.0f); } -MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_brightness_obj, protomatter_protomatter_get_brightness); -STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t value_in) { +STATIC mp_obj_t protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_obj_t value_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - bool paused = mp_obj_is_true(value_in); - common_hal_protomatter_protomatter_set_paused(self, paused); + mp_float_t brightness = mp_obj_get_float(value_in); + if (brightness < 0.0f || brightness > 1.0f) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + common_hal_protomatter_protomatter_set_paused(self_in, brightness <= 0); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_paused_obj, protomatter_protomatter_set_paused); +MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_brightness_obj, protomatter_protomatter_set_brightness); -const mp_obj_property_t protomatter_protomatter_paused_obj = { +const mp_obj_property_t protomatter_protomatter_brightness_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&protomatter_protomatter_get_paused_obj, - (mp_obj_t)&protomatter_protomatter_set_paused_obj, + .proxy = {(mp_obj_t)&protomatter_protomatter_get_brightness_obj, + (mp_obj_t)&protomatter_protomatter_set_brightness_obj, (mp_obj_t)&mp_const_none_obj}, }; -//| .. method:: swapbuffers() +//| .. method:: refresh() //| -//| Transmits the color data in the buffer to the pixels so that they are shown. +//| Transmits the color data in the buffer to the pixels so that +//| they are shown. //| -//| The data in the buffer must be in "RGB565" format. This means -//| that it is organized as a series of 16-bit numbers where the highest 5 -//| bits are interpreted as red, the next 6 as green, and the final 5 as -//| blue. The object can be any buffer, but `array.array` and `ulab.array` -//| objects are most often useful. -//| -STATIC mp_obj_t protomatter_protomatter_swapbuffers(mp_obj_t self_in) { +STATIC mp_obj_t protomatter_protomatter_refresh(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - - _PM_convert_565(&self->core, self->bufinfo.buf, self->width); - _PM_swapbuffer_maybe(&self->core); + common_hal_protomatter_protomatter_refresh(self); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_swapbuffers_obj, protomatter_protomatter_swapbuffers); +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_refresh_obj, protomatter_protomatter_refresh); STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&protomatter_protomatter_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&protomatter_protomatter_paused_obj) }, - { MP_ROM_QSTR(MP_QSTR_swapbuffers), MP_ROM_PTR(&protomatter_protomatter_swapbuffers_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&protomatter_protomatter_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&protomatter_protomatter_refresh_obj) }, }; STATIC MP_DEFINE_CONST_DICT(protomatter_protomatter_locals_dict, protomatter_protomatter_locals_dict_table); STATIC void protomatter_protomatter_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - + *bufinfo = self->bufinfo; } -// This version exists so that the return value of the function can be none, matching the protocol -STATIC void protomatter_protomatter_swapbuffers_void(mp_obj_t self_in) { - protomatter_protomatter_swapbuffers(self_in); +// These version exists so that the prototype matches the protocol, +// avoiding a type cast that can hide errors +STATIC void protomatter_protomatter_swapbuffers(mp_obj_t self_in) { + common_hal_protomatter_protomatter_refresh(self_in); } -// This version exists so that the return value of the function can be none, matching the protocol -STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { - protomatter_protomatter_deinit(self_in); +STATIC void protomatter_protomatter_deinit_proto(mp_obj_t self_in) { + common_hal_protomatter_protomatter_deinit(self_in); } -STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { +STATIC float protomatter_protomatter_get_brightness_proto(mp_obj_t self_in) { + return common_hal_protomatter_protomatter_get_paused(self_in) ? 0.0f : 1.0f; +} + +STATIC bool protomatter_protomatter_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); return true; } @@ -327,9 +336,10 @@ STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t STATIC const framebuffer_p_t protomatter_protomatter_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) .get_bufinfo = protomatter_protomatter_get_bufinfo, - .set_brightness = protomatter_protomatter_set_brightness, - .swapbuffers = protomatter_protomatter_swapbuffers_void, - .deinit = protomatter_protomatter_deinit_void, + .set_brightness = protomatter_protomatter_set_brightness_proto, + .get_brightness = protomatter_protomatter_get_brightness_proto, + .swapbuffers = protomatter_protomatter_swapbuffers, + .deinit = protomatter_protomatter_deinit_proto, }; STATIC mp_int_t protomatter_protomatter_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h index 0a52c556fc..9499da22c0 100644 --- a/shared-bindings/_protomatter/Protomatter.h +++ b/shared-bindings/_protomatter/Protomatter.h @@ -54,5 +54,6 @@ void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused); bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self); +void common_hal_protomatter_protomatter_refresh(protomatter_protomatter_obj_t* self); #endif diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 538d3afb46..aa8fc1a630 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -216,7 +216,7 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_brightness(mp_obj_t sel framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, false); mp_float_t brightness = mp_obj_get_float(brightness_obj); - if (brightness < 0 || brightness > 1.0) { + if (brightness < 0.0f || brightness > 1.0f) { mp_raise_ValueError(translate("Brightness must be 0-1.0")); } bool ok = common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index 56ef8abc47..b472088d20 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -60,9 +60,6 @@ void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_fram bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); -bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); -void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); - mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self); bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness); diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index 9f67bfad31..77ca634763 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -53,7 +53,7 @@ void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t self->oe_pin = oe_pin; self->latch_pin = latch_pin; self->doublebuffer = doublebuffer; - + self->timer = timer ? timer : common_hal_protomatter_timer_allocate(); if (self->timer == NULL) { mp_raise_ValueError(translate("No timer available")); @@ -90,7 +90,7 @@ void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_ } ProtomatterStatus stat = _PM_init(&self->core, - self->width, self->bit_depth, + self->width, self->bit_depth, self->rgb_count/6, self->rgb_pins, self->addr_count, self->addr_pins, self->clock_pin, self->latch_pin, self->oe_pin, @@ -192,3 +192,9 @@ void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self) { return self->paused; } + +void common_hal_protomatter_protomatter_refresh(protomatter_protomatter_obj_t* self) { + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + _PM_swapbuffer_maybe(&self->core); +} + diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 1ae127de21..b7f517ce5b 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -13,14 +13,14 @@ static inline void *_PM_allocator_impl(size_t sz) { if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); } else { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); return allocation ? allocation->ptr : NULL; } } static inline void _PM_free_impl(void *ptr_in) { supervisor_allocation *allocation = allocation_from_ptr(ptr_in); - + if (allocation) { free_memory(allocation); } From 0ce9c008c5d54f59224bda91af36c9c86aa64c09 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 14 Apr 2020 10:02:08 -0500 Subject: [PATCH 38/42] Protomatter: Make all arguments kw-only, add rgb count and optional height checking They're not readily distinguishable by type. I also added the requested height optional parameter; this is checked against the computed one. It's not feasible to use this parameter to artificailly reduce the number of used rows, because changes in the underlying C protomatter library would be required. Finally, I added a better error message when the number of RGB pins was not what was expected. --- shared-bindings/_protomatter/Protomatter.c | 34 +++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index cfc0ba6edf..bb43390796 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -177,17 +177,18 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ STATIC mp_obj_t protomatter_protomatter_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_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list, - ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer }; + ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED }, - { MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED }, - { MP_QSTR_rgb_pins, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_addr_pins, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_clock_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_latch_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_output_enable_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_doublebuffer, MP_ARG_BOOL, { .u_bool = true } }, - { MP_QSTR_framebuffer, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_rgb_pins, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_addr_pins, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_clock_pin, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_latch_pin, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_output_enable_pin, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, + { MP_QSTR_doublebuffer, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = true } }, + { MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -208,6 +209,19 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); + if (rgb_count % 6) { + mp_raise_ValueError_varg(translate("Must use a multiple of 6 rgb pins, not %d"), rgb_count); + } + + // TODO(@jepler) Use fewer than all rows of pixels if height < computed_height + if (args[ARG_height].u_int != 0) { + int computed_height = (rgb_count / 3) << (addr_count); + if (computed_height != args[ARG_height].u_int) { + mp_raise_ValueError_varg( + translate("%d address pins and %d rgb pins indicate a height of %d, not %d"), addr_count, rgb_count, computed_height, args[ARG_height].u_int); + } + } + preflight_pins_or_throw(clock_pin, rgb_pins, rgb_count, true); mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; From d8362ef654d86d29561db2cbcc2a20ab488316a8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 14 Apr 2020 17:34:53 -0500 Subject: [PATCH 39/42] displayio: swap colors in palettes too .. change the in-rom palette to be in RGB565 order --- shared-module/displayio/Palette.c | 7 ++++++- supervisor/shared/display.c | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index 3bce86f484..1ef03aab44 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -83,7 +83,12 @@ bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_col } else if (colorspace->grayscale) { *color = self->colors[palette_index].luma >> (8 - colorspace->depth); } else { - *color = self->colors[palette_index].rgb565; + uint16_t packed = self->colors[palette_index].rgb565; + if (colorspace->reverse_bytes_in_word) { + // swap bytes + packed = __builtin_bswap16(packed); + } + *color = packed; } return true; diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index cdf710d268..95926bc9c0 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -169,28 +169,28 @@ _displayio_color_t blinka_colors[7] = { }, { .rgb888 = 0x8428bc, - .rgb565 = 0x7889, + .rgb565 = 0x8978, .luma = 0xff, // We cheat the luma here. It is actually 0x60 .hue = 184, .chroma = 148 }, { .rgb888 = 0xff89bc, - .rgb565 = 0xB8FC, + .rgb565 = 0xFCB8, .luma = 0xb5, .hue = 222, .chroma = 118 }, { .rgb888 = 0x7beffe, - .rgb565 = 0x9F86, + .rgb565 = 0x869F, .luma = 0xe0, .hue = 124, .chroma = 131 }, { .rgb888 = 0x51395f, - .rgb565 = 0x0D5A, + .rgb565 = 0x5A0D, .luma = 0x47, .hue = 185, .chroma = 38 @@ -203,7 +203,7 @@ _displayio_color_t blinka_colors[7] = { }, { .rgb888 = 0x0736a0, - .rgb565 = 0xf501, + .rgb565 = 0x01f5, .luma = 0x44, .hue = 147, .chroma = 153 From 3c018bf7fd8142132bdd063a9c898188c825b2a7 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 14 Apr 2020 18:25:21 -0500 Subject: [PATCH 40/42] make translate --- locale/ID.po | 64 +++++++++++++++++++++++++++++++++++----- locale/circuitpython.pot | 64 +++++++++++++++++++++++++++++++++++----- locale/de_DE.po | 64 +++++++++++++++++++++++++++++++++++----- locale/en_US.po | 64 +++++++++++++++++++++++++++++++++++----- locale/en_x_pirate.po | 64 +++++++++++++++++++++++++++++++++++----- locale/es.po | 64 +++++++++++++++++++++++++++++++++++----- locale/fil.po | 64 +++++++++++++++++++++++++++++++++++----- locale/fr.po | 64 +++++++++++++++++++++++++++++++++++----- locale/it_IT.po | 64 +++++++++++++++++++++++++++++++++++----- locale/ko.po | 64 +++++++++++++++++++++++++++++++++++----- locale/pl.po | 64 +++++++++++++++++++++++++++++++++++----- locale/pt_BR.po | 64 +++++++++++++++++++++++++++++++++++----- locale/zh_Latn_pinyin.po | 64 +++++++++++++++++++++++++++++++++++----- 13 files changed, 728 insertions(+), 104 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index ab8aa844c8..5715f446f5 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -53,6 +53,11 @@ msgstr "output:\n" msgid "%%c requires int or char" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" @@ -283,7 +288,7 @@ msgstr "Semua timer untuk pin ini sedang digunakan" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Semua timer sedang digunakan" @@ -323,6 +328,10 @@ msgstr "" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -340,6 +349,7 @@ msgstr "" "menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -355,7 +365,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "Kedua pin harus mendukung hardware interrut" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -364,6 +376,7 @@ msgid "Brightness must be between 0 and 255" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -378,10 +391,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -641,11 +656,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -763,6 +780,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -851,7 +869,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "" @@ -906,7 +924,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Pin tidak valid" @@ -1021,6 +1039,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1104,6 +1127,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1180,6 +1207,14 @@ msgstr "Pin tidak mempunya kemampuan untuk ADC (Analog Digital Converter)" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Tambahkan module apapun pada filesystem\n" @@ -1198,6 +1233,11 @@ msgstr "" "Tekan tombol apa saja untuk masuk ke dalam REPL. Gunakan CTRL+D untuk reset " "(Reload)" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1392,13 +1432,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "Terlalu banyak channel dalam sampel" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2779,6 +2817,16 @@ msgstr "anotasi return harus sebuah identifier" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a421b4ef18..a679a0b6e2 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -53,6 +53,11 @@ msgstr "" msgid "%%c requires int or char" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" @@ -281,7 +286,7 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "" @@ -321,6 +326,10 @@ msgstr "" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -336,6 +345,7 @@ msgid "" msgstr "" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -351,7 +361,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -360,6 +372,7 @@ msgid "Brightness must be between 0 and 255" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -374,10 +387,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -630,11 +645,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -752,6 +769,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -840,7 +858,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "" @@ -895,7 +913,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "" @@ -1010,6 +1028,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1093,6 +1116,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1168,6 +1195,14 @@ msgstr "" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1184,6 +1219,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1376,13 +1416,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2754,6 +2792,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index ec343d7f20..9c65306058 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -55,6 +55,11 @@ msgstr " Ausgabe:\n" msgid "%%c requires int or char" msgstr "%%c erwartet int oder char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in Benutzung" @@ -283,7 +288,7 @@ msgstr "Alle timer für diesen Pin werden bereits benutzt" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Alle timer werden benutzt" @@ -323,6 +328,10 @@ msgstr "Array muss Halbwörter enthalten (type 'H')" msgid "Array values should be single bytes." msgstr "Array-Werte sollten aus Einzelbytes bestehen." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -340,6 +349,7 @@ msgstr "" "auszuführen oder verbinde dich mit der REPL zum Deaktivieren.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "Unterhalb der minimalen Frame Rate" @@ -355,7 +365,9 @@ msgstr "Bit depth muss ein Vielfaches von 8 sein." msgid "Both pins must support hardware interrupts" msgstr "Beide pins müssen Hardware Interrupts unterstützen" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "Die Helligkeit muss zwischen 0 und 1.0 liegen" @@ -364,6 +376,7 @@ msgid "Brightness must be between 0 and 255" msgstr "Die Helligkeit muss zwischen 0 und 255 liegen" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "Die Helligkeit ist nicht einstellbar" @@ -378,10 +391,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Der Puffergröße ist inkorrekt. Sie sollte %d bytes haben." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "Der Puffer ist kein Byte-Array" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "Der Puffer ist zu klein" @@ -634,11 +649,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "Display muss einen 16 Bit Farbraum haben." #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen" @@ -758,6 +775,7 @@ msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Gruppe schon benutzt" @@ -848,7 +866,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Ungültiges Argument" @@ -903,7 +921,7 @@ msgstr "Ungültige Phase" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Ungültiger Pin" @@ -1019,6 +1037,11 @@ msgstr "Muss eine %q Unterklasse sein." msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1102,6 +1125,10 @@ msgstr "Kein Speicherplatz mehr verfügbar auf dem Gerät" msgid "No such file/directory" msgstr "Keine solche Datei/Verzeichnis" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1183,6 +1210,14 @@ msgstr "Pin hat keine ADC Funktionalität" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "und alle Module im Dateisystem \n" @@ -1201,6 +1236,11 @@ msgstr "" "Drücke eine Taste um dich mit der REPL zu verbinden. Drücke Strg-D zum neu " "laden" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull wird nicht verwendet, wenn die Richtung output ist." @@ -1395,13 +1435,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "Zu viele Kanäle im sample" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Zu viele displays" @@ -2792,6 +2830,16 @@ msgstr "return annotation muss ein identifier sein" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/en_US.po b/locale/en_US.po index a28fc10302..b753d40a7d 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -53,6 +53,11 @@ msgstr "" msgid "%%c requires int or char" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" @@ -281,7 +286,7 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "" @@ -321,6 +326,10 @@ msgstr "" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -336,6 +345,7 @@ msgid "" msgstr "" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -351,7 +361,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -360,6 +372,7 @@ msgid "Brightness must be between 0 and 255" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -374,10 +387,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -630,11 +645,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -752,6 +769,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -840,7 +858,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "" @@ -895,7 +913,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "" @@ -1010,6 +1028,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1093,6 +1116,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1168,6 +1195,14 @@ msgstr "" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1184,6 +1219,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1376,13 +1416,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2754,6 +2792,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index 946c3af24f..57c6500a20 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -55,6 +55,11 @@ msgstr "" msgid "%%c requires int or char" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "" @@ -283,7 +288,7 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "" @@ -323,6 +328,10 @@ msgstr "" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -340,6 +349,7 @@ msgstr "" "t' the REPL t' scuttle.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -355,7 +365,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -364,6 +376,7 @@ msgid "Brightness must be between 0 and 255" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -378,10 +391,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -634,11 +649,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -756,6 +773,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -844,7 +862,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "" @@ -899,7 +917,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "" @@ -1014,6 +1032,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1097,6 +1120,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1172,6 +1199,14 @@ msgstr "Belay that! Th' Pin be not ADC capable" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1188,6 +1223,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1380,13 +1420,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2758,6 +2796,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/es.po b/locale/es.po index f3f6c45914..b1cfbad702 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -55,6 +55,11 @@ msgstr " salida:\n" msgid "%%c requires int or char" msgstr "%%c requiere int o char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q está siendo utilizado" @@ -285,7 +290,7 @@ msgstr "Todos los timers para este pin están siendo utilizados" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Todos los timers en uso" @@ -325,6 +330,10 @@ msgstr "Array debe contener media palabra (type 'H')" msgid "Array values should be single bytes." msgstr "Valores del array deben ser bytes individuales." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -342,6 +351,7 @@ msgstr "" "ejecutarlos o entra al REPL para desabilitarlos.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -357,7 +367,9 @@ msgstr "Bits depth debe ser múltiplo de 8." msgid "Both pins must support hardware interrupts" msgstr "Ambos pines deben soportar interrupciones por hardware" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -366,6 +378,7 @@ msgid "Brightness must be between 0 and 255" msgstr "El brillo debe estar entro 0 y 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "El brillo no se puede ajustar" @@ -380,10 +393,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Tamaño de buffer incorrecto. Debe ser de %d bytes." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -636,11 +651,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "Rotación de display debe ser en incrementos de 90 grados" @@ -758,6 +775,7 @@ msgstr "La función requiere lock" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -848,7 +866,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -903,7 +921,7 @@ msgstr "Fase inválida" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Pin inválido" @@ -1018,6 +1036,11 @@ msgstr "Debe de ser una subclase de %q" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1101,6 +1124,10 @@ msgstr "No queda espacio en el dispositivo" msgid "No such file/directory" msgstr "No existe el archivo/directorio" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1182,6 +1209,14 @@ msgstr "Pin no tiene capacidad ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c #, fuzzy msgid "Plus any modules on the filesystem\n" @@ -1200,6 +1235,11 @@ msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull no se usa cuando la dirección es output." @@ -1393,13 +1433,11 @@ msgstr "Ancho del Tile debe dividir exactamente el ancho de mapa de bits" msgid "Too many channels in sample." msgstr "Demasiados canales en sample." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "Demasiados buses de pantalla" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Muchos displays" @@ -2792,6 +2830,16 @@ msgstr "la anotación de retorno debe ser un identificador" msgid "return expected '%q' but got '%q'" msgstr "retorno esperado '%q' pero se obtuvo '%q'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/fil.po b/locale/fil.po index 44da9b7557..4049cce7d3 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -53,6 +53,11 @@ msgstr " output:\n" msgid "%%c requires int or char" msgstr "%%c nangangailangan ng int o char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q ay ginagamit" @@ -285,7 +290,7 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Lahat ng timer ginagamit" @@ -325,6 +330,10 @@ msgstr "May halfwords (type 'H') dapat ang array" msgid "Array values should be single bytes." msgstr "Array values ay dapat single bytes." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -342,6 +351,7 @@ msgstr "" "para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -357,7 +367,9 @@ msgstr "Bit depth ay dapat multiple ng 8." msgid "Both pins must support hardware interrupts" msgstr "Ang parehong mga pin ay dapat na sumusuporta sa hardware interrupts" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -366,6 +378,7 @@ msgid "Brightness must be between 0 and 255" msgstr "Ang liwanag ay dapat sa gitna ng 0 o 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -380,10 +393,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Mali ang size ng buffer. Dapat %d bytes." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -642,11 +657,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -766,6 +783,7 @@ msgstr "Function nangangailangan ng lock" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -856,7 +874,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Maling argumento" @@ -911,7 +929,7 @@ msgstr "Mali ang phase" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Mali ang pin" @@ -1026,6 +1044,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1109,6 +1132,10 @@ msgstr "" msgid "No such file/directory" msgstr "Walang file/directory" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1188,6 +1215,14 @@ msgstr "Ang pin ay walang kakayahan sa ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Kasama ang kung ano pang modules na sa filesystem\n" @@ -1206,6 +1241,11 @@ msgstr "" "Pindutin ang anumang key upang pumasok sa REPL. Gamitin ang CTRL-D upang i-" "reload." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull hindi ginagamit kapag ang direksyon ay output." @@ -1399,13 +1439,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "Sobra ang channels sa sample." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2806,6 +2844,16 @@ msgstr "return annotation ay dapat na identifier" msgid "return expected '%q' but got '%q'" msgstr "return umasa ng '%q' pero ang nakuha ay ‘%q’" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 17746f41fd..54f4d06450 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -55,6 +55,11 @@ msgstr " sortie:\n" msgid "%%c requires int or char" msgstr "%%c nécessite un entier 'int' ou un caractère 'char'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q utilisé" @@ -288,7 +293,7 @@ msgstr "Tous les timers pour cette broche sont utilisés" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Tous les timers sont utilisés" @@ -329,6 +334,10 @@ msgstr "Le tableau doit contenir des demi-mots (type 'H')" msgid "Array values should be single bytes." msgstr "Les valeurs du tableau doivent être des octets simples 'bytes'." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -346,6 +355,7 @@ msgstr "" "lancer ou entrez sur REPL pour le désactiver.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -361,7 +371,9 @@ msgstr "La profondeur de bit doit être un multiple de 8." msgid "Both pins must support hardware interrupts" msgstr "Les deux entrées doivent supporter les interruptions matérielles" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -370,6 +382,7 @@ msgid "Brightness must be between 0 and 255" msgstr "La luminosité doit être entre 0 et 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "Luminosité non-ajustable" @@ -384,10 +397,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Tampon de taille incorrect. Devrait être de %d octets." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -645,11 +660,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés" @@ -769,6 +786,7 @@ msgstr "La fonction nécessite un verrou" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -860,7 +878,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Argument invalide" @@ -917,7 +935,7 @@ msgstr "Phase invalide" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Broche invalide" @@ -1033,6 +1051,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1116,6 +1139,10 @@ msgstr "Il n'y a plus d'espace libre sur le périphérique" msgid "No such file/directory" msgstr "Fichier/dossier introuvable" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1202,6 +1229,14 @@ msgstr "La broche ne peut être utilisée pour l'ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c #, fuzzy msgid "Plus any modules on the filesystem\n" @@ -1219,6 +1254,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." @@ -1414,13 +1454,11 @@ msgstr "La largeur de la tuile doit diviser exactement la largeur de l'image" msgid "Too many channels in sample." msgstr "Trop de canaux dans l'échantillon." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "Trop de bus d'affichage" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Trop d'affichages" @@ -2838,6 +2876,16 @@ msgstr "l'annotation de return doit être un identifiant" msgid "return expected '%q' but got '%q'" msgstr "return attendait '%q' mais a reçu '%q'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 1717f20f95..5111c3eef6 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -53,6 +53,11 @@ msgstr " output:\n" msgid "%%c requires int or char" msgstr "%%c necessita di int o char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q in uso" @@ -284,7 +289,7 @@ msgstr "Tutti i timer per questo pin sono in uso" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Tutti i timer utilizzati" @@ -324,6 +329,10 @@ msgstr "Array deve avere mezzoparole (typo 'H')" msgid "Array values should be single bytes." msgstr "Valori di Array dovrebbero essere bytes singulari" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -341,6 +350,7 @@ msgstr "" "per disabilitarlo.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -357,7 +367,9 @@ msgstr "La profondità di bit deve essere multipla di 8." msgid "Both pins must support hardware interrupts" msgstr "Entrambi i pin devono supportare gli interrupt hardware" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -366,6 +378,7 @@ msgid "Brightness must be between 0 and 255" msgstr "La luminosità deve essere compreso tra 0 e 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "Illiminazione non è regolabile" @@ -380,10 +393,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -642,11 +657,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -766,6 +783,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -856,7 +874,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Argomento non valido" @@ -913,7 +931,7 @@ msgstr "Fase non valida" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Pin non valido" @@ -1030,6 +1048,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1113,6 +1136,10 @@ msgstr "Non che spazio sul dispositivo" msgid "No such file/directory" msgstr "Nessun file/directory esistente" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1197,6 +1224,14 @@ msgstr "Il pin non ha capacità di ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c #, fuzzy msgid "Plus any modules on the filesystem\n" @@ -1215,6 +1250,11 @@ msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" "Premi un qualunque tasto per entrare nel REPL. Usa CTRL-D per ricaricare." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1410,13 +1450,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Troppi schermi" @@ -2813,6 +2851,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "return aspettava '%q' ma ha ottenuto '%q'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 9a1770f33b..6fb1789551 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2019-05-06 14:22-0700\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" @@ -55,6 +55,11 @@ msgstr " 산출:\n" msgid "%%c requires int or char" msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q 사용 중입니다" @@ -283,7 +288,7 @@ msgstr "핀의 모든 타이머가 사용 중입니다" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "모든 타이머가 사용 중입니다" @@ -323,6 +328,10 @@ msgstr "" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -340,6 +349,7 @@ msgstr "" "성화하려면 REPL을 입력하십시오.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -355,7 +365,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -364,6 +376,7 @@ msgid "Brightness must be between 0 and 255" msgstr "밝기는 0에서 255 사이 여야합니다" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "밝기를 조절할 수 없습니다" @@ -378,10 +391,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "잘못된 크기의 버퍼. %d 바이트 여야합니다." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -634,11 +649,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -756,6 +773,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -844,7 +862,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "" @@ -899,7 +917,7 @@ msgstr "단계가 잘못되었습니다" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "핀이 잘못되었습니다" @@ -1014,6 +1032,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1097,6 +1120,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1172,6 +1199,14 @@ msgstr "" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1188,6 +1223,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1380,13 +1420,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "" -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2759,6 +2797,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/pl.po b/locale/pl.po index d26dff9416..49442ceb1c 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -54,6 +54,11 @@ msgstr " wyjście:\n" msgid "%%c requires int or char" msgstr "%%c wymaga int lub char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q w użyciu" @@ -282,7 +287,7 @@ msgstr "Wszystkie timery tej nóżki w użyciu" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Wszystkie timery w użyciu" @@ -322,6 +327,10 @@ msgstr "Tablica musi zawierać pół-słowa (typ 'H')" msgid "Array values should be single bytes." msgstr "Wartości powinny być bajtami." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -339,6 +348,7 @@ msgstr "" "uruchomić, albo wejdź w konsolę aby wyłączyć.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -354,7 +364,9 @@ msgstr "Głębia musi być wielokrotnością 8." msgid "Both pins must support hardware interrupts" msgstr "Obie nóżki muszą wspierać przerwania sprzętowe" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -363,6 +375,7 @@ msgid "Brightness must be between 0 and 255" msgstr "Jasność musi być pomiędzy 0 a 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "Jasność nie jest regulowana" @@ -377,10 +390,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Zła wielkość bufora. Powinno być %d bajtów." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -633,11 +648,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "Wyświetlacz można obracać co 90 stopni" @@ -755,6 +772,7 @@ msgstr "Funkcja wymaga blokady" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -845,7 +863,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Zły argument" @@ -900,7 +918,7 @@ msgstr "Zła faza" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Zła nóżka" @@ -1015,6 +1033,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1098,6 +1121,10 @@ msgstr "Brak miejsca" msgid "No such file/directory" msgstr "Brak pliku/katalogu" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1173,6 +1200,14 @@ msgstr "Nóżka nie obsługuje ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Oraz moduły w systemie plików\n" @@ -1189,6 +1224,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Dowolny klawisz aby uruchomić konsolę. CTRL-D aby przeładować." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Podciągnięcie nieużywane w trybie wyjścia." @@ -1381,13 +1421,11 @@ msgstr "Szerokość bitmapy musi być wielokrotnością szerokości kafelka" msgid "Too many channels in sample." msgstr "Zbyt wiele kanałów." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "Zbyt wiele magistrali" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Zbyt wiele wyświetlaczy" @@ -2764,6 +2802,16 @@ msgstr "anotacja wartości musi być identyfikatorem" msgid "return expected '%q' but got '%q'" msgstr "return oczekiwał '%q', a jest '%q'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 153dadd910..197d57d02b 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -53,6 +53,11 @@ msgstr " saída:\n" msgid "%%c requires int or char" msgstr "%%c requer int ou char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q em uso" @@ -284,7 +289,7 @@ msgstr "Todos os temporizadores para este pino estão em uso" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Todos os temporizadores em uso" @@ -324,6 +329,10 @@ msgstr "Array deve conter meias palavras (tipo 'H')" msgid "Array values should be single bytes." msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "" @@ -339,6 +348,7 @@ msgid "" msgstr "" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "" @@ -354,7 +364,9 @@ msgstr "" msgid "Both pins must support hardware interrupts" msgstr "Ambos os pinos devem suportar interrupções de hardware" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "" @@ -363,6 +375,7 @@ msgid "Brightness must be between 0 and 255" msgstr "O brilho deve estar entre 0 e 255" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "" @@ -377,10 +390,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Buffer de tamanho incorreto. Deve ser %d bytes." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "" @@ -637,11 +652,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "" @@ -761,6 +778,7 @@ msgstr "" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "" @@ -849,7 +867,7 @@ msgstr "" msgid "Invalid UART pin selection" msgstr "" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -906,7 +924,7 @@ msgstr "Fase Inválida" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Pino inválido" @@ -1022,6 +1040,11 @@ msgstr "" msgid "Must provide MISO or MOSI pin" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1105,6 +1128,10 @@ msgstr "" msgid "No such file/directory" msgstr "" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "" @@ -1183,6 +1210,14 @@ msgstr "O pino não tem recursos de ADC" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c #, fuzzy msgid "Plus any modules on the filesystem\n" @@ -1200,6 +1235,11 @@ msgstr "" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1393,13 +1433,11 @@ msgstr "" msgid "Too many channels in sample." msgstr "Muitos canais na amostra." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "" @@ -2776,6 +2814,16 @@ msgstr "" msgid "return expected '%q' but got '%q'" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index d1c0d5b79c..457e35b625 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-13 19:22-0500\n" +"POT-Creation-Date: 2020-04-14 18:26-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -60,6 +60,11 @@ msgstr " shūchū:\n" msgid "%%c requires int or char" msgstr "%%c xūyào zhěngshù huò char" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "%d address pins and %d rgb pins indicate a height of %d, not %d" +msgstr "" + #: shared-bindings/microcontroller/Pin.c msgid "%q in use" msgstr "%q zhèngzài shǐyòng" @@ -288,7 +293,7 @@ msgstr "Cǐ yǐn jiǎo de suǒyǒu jìshí qì zhèngzài shǐyòng" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c shared-bindings/pulseio/PWMOut.c +#: ports/nrf/peripherals/nrf/timers.c shared-bindings/pulseio/PWMOut.c #: shared-module/_pew/PewPew.c msgid "All timers in use" msgstr "Suǒyǒu jìshí qì shǐyòng" @@ -328,6 +333,10 @@ msgstr "Shùzǔ bìxū bāohán bàn zìshù (type 'H')" msgid "Array values should be single bytes." msgstr "Shùzǔ zhí yīnggāi shì dāngè zì jié." +#: shared-bindings/_protomatter/Protomatter.c +msgid "At most %d %q may be specified (not %d)" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." msgstr "MicroPython VM zài wèi yùnxíng shí chángshì fēnpèi duī." @@ -345,6 +354,7 @@ msgstr "" "huò shūrù REPL jìnyòng.\n" #: shared-module/displayio/Display.c +#: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" msgstr "Dī yú zuìdī zhèng sùlǜ" @@ -360,7 +370,9 @@ msgstr "Bǐtè shēndù bìxū shì 8 bèi yǐshàng." msgid "Both pins must support hardware interrupts" msgstr "Liǎng gè yǐn jiǎo dōu bìxū zhīchí yìngjiàn zhōngduàn" +#: shared-bindings/_protomatter/Protomatter.c #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness must be 0-1.0" msgstr "Liàngdù bìxū wèi 0-1.0" @@ -369,6 +381,7 @@ msgid "Brightness must be between 0 and 255" msgstr "Liàngdù bìxū jiè yú 0 dào 255 zhī jiān" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" msgstr "Liàngdù wúfǎ tiáozhěng" @@ -383,10 +396,12 @@ msgid "Buffer incorrect size. Should be %d bytes." msgstr "Huǎnchōng qū dàxiǎo bù zhèngquè. Yīnggāi shì %d zì jié." #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." msgstr "Huǎnchōng qū bùshì bytearray" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" msgstr "Huǎnchōng qū tài xiǎo" @@ -641,11 +656,13 @@ msgid "DigitalInOut not supported on given pin" msgstr "Gěi dìng de yǐn jiǎo bù zhīchí DigitalInOut" #: shared-bindings/displayio/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." msgstr "Xiǎnshì bìxū jùyǒu 16 wèi yánsè kōngjiān." #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" msgstr "Xiǎnshì xuánzhuǎn bìxū 90 dù jiā xīn" @@ -763,6 +780,7 @@ msgstr "Hánshù xūyào suǒdìng" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Group already used" msgstr "Jítuán yǐjīng shǐyòngguò" @@ -853,7 +871,7 @@ msgstr "Wúxiào de SPI yǐn jiǎo xuǎnzé" msgid "Invalid UART pin selection" msgstr "Wúxiào de UART yǐn jiǎo xuǎnzé" -#: py/moduerrno.c +#: py/moduerrno.c shared-module/_protomatter/Protomatter.c msgid "Invalid argument" msgstr "Wúxiào de cānshù" @@ -908,7 +926,7 @@ msgstr "Jiēduàn wúxiào" #: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c -#: shared-bindings/pulseio/PWMOut.c +#: shared-bindings/pulseio/PWMOut.c shared-module/_protomatter/Protomatter.c msgid "Invalid pin" msgstr "Wúxiào de yǐn jiǎo" @@ -1023,6 +1041,11 @@ msgstr "Bìxū shì %q zi lèi." msgid "Must provide MISO or MOSI pin" msgstr "Bìxū tígōng MISO huò MOSI yǐn jiǎo" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "" + #: py/parse.c msgid "Name too long" msgstr "" @@ -1106,6 +1129,10 @@ msgstr "Shèbèi shàng méiyǒu kònggé" msgid "No such file/directory" msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù" +#: shared-module/_protomatter/Protomatter.c +msgid "No timer available" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Nordic Soft Device failure assertion." msgstr "Nordic ruǎn shèbèi gùzhàng shēngmíng." @@ -1187,6 +1214,14 @@ msgstr "Pin méiyǒu ADC nénglì" msgid "Pin number already reserved by EXTI" msgstr "" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n" @@ -1203,6 +1238,11 @@ msgstr "Qiánzhuì huǎnchōng qū bìxū zài duī shàng" msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Àn xià rènhé jiàn jìnrù REPL. Shǐyòng CTRL-D chóngxīn jiāzài." +#: shared-module/_protomatter/Protomatter.c +#, c-format +msgid "Protomatter internal error #%d" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Fāngxiàng shūchū shí Pull méiyǒu shǐyòng." @@ -1402,13 +1442,11 @@ msgstr "Píng pū kuāndù bìxū huàfēn wèi tú kuāndù" msgid "Too many channels in sample." msgstr "Chōuyàng zhōng de píndào tài duō." -#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c -#: shared-bindings/displayio/ParallelBus.c +#: shared-module/displayio/__init__.c msgid "Too many display busses" msgstr "Xiǎnshì zǒngxiàn tài duōle" -#: shared-bindings/displayio/Display.c -#: shared-bindings/displayio/EPaperDisplay.c +#: shared-module/displayio/__init__.c msgid "Too many displays" msgstr "Xiǎnshì tài duō" @@ -2793,6 +2831,16 @@ msgstr "fǎnhuí zhùshì bìxū shì biāozhì fú" msgid "return expected '%q' but got '%q'" msgstr "fǎnhuí yùqí de '%q' dàn huòdéle '%q'" +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "" + +#: shared-bindings/_protomatter/Protomatter.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "right hand side must be an ndarray, or a scalar" msgstr "" From ebd98bfc7b317bf28ebaccd8daf63c0d65087ea4 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 14 Apr 2020 16:50:08 -0700 Subject: [PATCH 41/42] Update to the Adafruit Community Code of Conduct It better reflects our standards and also addresses chats. History of how it evolved from the Contributor Covenant is here: https://github.com/adafruit/Adafruit_Community_Code_of_Conduct/commits/master --- CODE_OF_CONDUCT.md | 127 ++++++++++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1617586f3a..134d51026a 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,74 +1,129 @@ -# Contributor Covenant Code of Conduct +# Adafruit Community Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and +contributors and leaders pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. +size, disability, ethnicity, gender identity and expression, level or type of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. ## Our Standards +We are committed to providing a friendly, safe and welcoming environment for +all. + Examples of behavior that contributes to creating a positive environment include: +* Be kind and courteous to others * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences +* Collaborating with other community members * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or -advances +* The use of sexualized language or imagery and sexual attention or advances +* The use of inappropriate images, including in a community member's avatar +* The use of inappropriate language, including in a community member's nickname +* Any spamming, flaming, baiting or other attention-stealing behavior +* Excessive or unwelcome helping; answering outside the scope of the question + asked * Trolling, insulting/derogatory comments, and personal or political attacks +* Promoting or spreading disinformation, lies, or conspiracy theories against + a person, group, organisation, project, or community * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +* Other conduct which could reasonably be considered inappropriate + +The goal of the standards and moderation guidelines outlined here is to build +and maintain a respectful community. We ask that you don’t just aim to be +"technically unimpeachable", but rather try to be your best self. + +We value many things beyond technical expertise, including collaboration and +supporting others within our community. Providing a positive experience for +other community members can have a much more significant impact than simply +providing the correct answer. ## Our Responsibilities -Project maintainers are responsible for clarifying the standards of acceptable +Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions +Project leaders have the right and responsibility to remove, edit, or +reject messages, comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. +permanently any community member for other behaviors that they deem +inappropriate, threatening, offensive, or harmful. + +## Moderation + +Instances of behaviors that violate the Adafruit Community Code of Conduct +may be reported by any member of the community. Community members are +encouraged to report these situations, including situations they witness +involving other community members. + +You may report in the following ways: + +In any situation, you may send an email to . + +On the Adafruit Discord, you may send an open message from any channel +to all Community Moderators by tagging @community moderators. You may +also send an open message from any channel, or a direct message to +@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442, +@sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175. + +Email and direct message reports will be kept confidential. + +In situations on Discord where the issue is particularly egregious, possibly +illegal, requires immediate action, or violates the Discord terms of service, +you should also report the message directly to Discord. + +These are the steps for upholding our community’s standards of conduct. + +1. Any member of the community may report any situation that violates the +Adafruit Community Code of Conduct. All reports will be reviewed and +investigated. +2. If the behavior is an egregious violation, the community member who +committed the violation may be banned immediately, without warning. +3. Otherwise, moderators will first respond to such behavior with a warning. +4. Moderators follow a soft "three strikes" policy - the community member may +be given another chance, if they are receptive to the warning and change their +behavior. +5. If the community member is unreceptive or unreasonable when warned by a +moderator, or the warning goes unheeded, they may be banned for a first or +second offense. Repeated offenses will result in the community member being +banned. ## Scope +This Code of Conduct and the enforcement policies listed above apply to all +Adafruit Community venues. This includes but is not limited to any community +spaces (both public and private), the entire Adafruit Discord server, and +Adafruit GitHub repositories. Examples of Adafruit Community spaces include +but are not limited to meet-ups, audio chats on the Adafruit Discord, or +interaction at a conference. + This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at support@adafruit.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. +when an individual is representing the project or its community. As a community +member, you are representing our community, and are expected to behave +accordingly. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +, +and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ +For other projects adopting the Adafruit Community Code of +Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider +explicitly mentioning your moderation policy or making a copy with your +own moderation policy so as to avoid confusion. From 11d6e177c091eb478aad595ae37f13f890ca6ead Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 14 Apr 2020 19:56:36 -0400 Subject: [PATCH 42/42] Fix my discord username --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 134d51026a..7eb8d93eae 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -76,7 +76,7 @@ In any situation, you may send an email to . On the Adafruit Discord, you may send an open message from any channel to all Community Moderators by tagging @community moderators. You may also send an open message from any channel, or a direct message to -@kattni#1507, @tannewt#4653, @Dan Halbert#1614, @cater#2442, +@kattni#1507, @tannewt#4653, @danh#1614, @cater#2442, @sommersoft#0222, @Mr. Certainly#0472 or @Andon#8175. Email and direct message reports will be kept confidential.