Merge pull request #2085 from tannewt/epd

Rework display refresh, add M4SK and add ePaper support
This commit is contained in:
Scott Shawcroft 2019-08-27 10:06:14 -07:00 committed by GitHub
commit 42956a62a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
78 changed files with 2508 additions and 656 deletions

View File

@ -35,8 +35,9 @@ env:
- TRAVIS_BOARDS="itsybitsy_m0_express metro_m0_express pirkey_m0 pyruler trinket_m0 trinket_m0_haxpress arduino_mkr1300 arduino_mkrzero arduino_zero bast_pro_mini_m0 catwan_usbstick datum_distance datum_imu datum_weather" TRAVIS_SDK=arm - TRAVIS_BOARDS="itsybitsy_m0_express metro_m0_express pirkey_m0 pyruler trinket_m0 trinket_m0_haxpress arduino_mkr1300 arduino_mkrzero arduino_zero bast_pro_mini_m0 catwan_usbstick datum_distance datum_imu datum_weather" TRAVIS_SDK=arm
- TRAVIS_BOARDS="escornabot_makech meowmeow pewpew10 robohatmm1_m0 snekboard sparkfun_lumidrive sparkfun_redboard_turbo sparkfun_samd21_dev sparkfun_samd21_mini uchip ugame10" TRAVIS_SDK=arm - TRAVIS_BOARDS="escornabot_makech meowmeow pewpew10 robohatmm1_m0 snekboard sparkfun_lumidrive sparkfun_redboard_turbo sparkfun_samd21_dev sparkfun_samd21_mini uchip ugame10" TRAVIS_SDK=arm
# Adafruit SAMD51 (M4) + Other SAMD51 # Adafruit SAMD51 (M4) + Other SAMD51
- TRAVIS_BOARDS="feather_m4_express grandcentral_m4_express itsybitsy_m4_express metro_m4_airlift_lite metro_m4_express pybadge pybadge_airlift pygamer pygamer_advance" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m4_express grandcentral_m4_express itsybitsy_m4_express metro_m4_airlift_lite metro_m4_express pybadge pybadge_airlift" TRAVIS_SDK=arm
- TRAVIS_BOARDS="pyportal pyportal_titano trellis_m4_express capablerobot_usbhub cp32-m4 datalore_ip_m4 datum_light kicksat-sprite mini_sam_m4 robohatmm1_m4 sam32" TRAVIS_SDK=arm - TRAVIS_BOARDS="pyportal pyportal_titano trellis_m4_express capablerobot_usbhub cp32-m4 datalore_ip_m4 datum_light" TRAVIS_SDK=arm
- TRAVIS_BOARDS="pygamer pygamer_advance monster_m4sk kicksat-sprite mini_sam_m4 robohatmm1_m4 sam32" TRAVIS_SDK=arm
addons: addons:

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -301,6 +301,10 @@ msgstr ""
"Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk " "Auto-reload aktif. Silahkan simpan data-data (files) melalui USB untuk "
"menjalankannya atau masuk ke REPL untukmenonaktifkan.\n" "menjalankannya atau masuk ke REPL untukmenonaktifkan.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit" msgstr "Bit clock dan word harus memiliki kesamaan pada clock unit"
@ -533,6 +537,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -749,6 +754,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1026,8 +1032,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1104,6 +1110,10 @@ msgstr "sistem file (filesystem) bersifat Read-only"
msgid "Read-only object" msgid "Read-only object"
msgstr "sistem file (filesystem) bersifat Read-only" msgstr "sistem file (filesystem) bersifat Read-only"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Channel Kanan tidak didukung" msgstr "Channel Kanan tidak didukung"
@ -1218,11 +1228,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1244,6 +1254,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1315,7 +1326,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Baudrate tidak didukung" msgstr "Baudrate tidak didukung"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Baudrate tidak didukung" msgstr "Baudrate tidak didukung"
@ -2198,6 +2209,11 @@ msgstr "tidak ada ikatan/bind pada temuan nonlocal"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "tidak ada modul yang bernama '%q'" msgstr "tidak ada modul yang bernama '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -297,6 +297,10 @@ msgid ""
"disable.\n" "disable.\n"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "" msgstr ""
@ -522,6 +526,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -734,6 +739,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1010,8 +1016,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1085,6 +1091,10 @@ msgstr ""
msgid "Read-only object" msgid "Read-only object"
msgstr "" msgstr ""
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "" msgstr ""
@ -1195,11 +1205,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1221,6 +1231,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1292,7 +1303,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "" msgstr ""
@ -2163,6 +2174,11 @@ msgstr ""
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "" msgstr ""
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n" "Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@ -301,6 +301,10 @@ msgstr ""
"Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie " "Automatisches Neuladen ist aktiv. Speichere Dateien über USB um sie "
"auszuführen oder verbinde dich mit der REPL zum Deaktivieren.\n" "auszuführen oder verbinde dich mit der REPL zum Deaktivieren.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Bit clock und word select müssen eine clock unit teilen" msgstr "Bit clock und word select müssen eine clock unit teilen"
@ -526,6 +530,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen" msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen"
@ -738,6 +743,7 @@ msgid "Function requires lock"
msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde" msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1025,8 +1031,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1102,6 +1108,10 @@ msgstr "Schreibgeschützte Dateisystem"
msgid "Read-only object" msgid "Read-only object"
msgstr "Schreibgeschützte Objekt" msgstr "Schreibgeschützte Objekt"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Rechter Kanal wird nicht unterstützt" msgstr "Rechter Kanal wird nicht unterstützt"
@ -1224,11 +1234,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1250,6 +1260,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Zu viele displays" msgstr "Zu viele displays"
@ -1323,7 +1334,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Baudrate wird nicht unterstützt" msgstr "Baudrate wird nicht unterstützt"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Nicht unterstützter display bus type" msgstr "Nicht unterstützter display bus type"
@ -2210,6 +2221,11 @@ msgstr ""
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "Kein Modul mit dem Namen '%q'" msgstr "Kein Modul mit dem Namen '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@ -297,6 +297,10 @@ msgid ""
"disable.\n" "disable.\n"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "" msgstr ""
@ -522,6 +526,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -734,6 +739,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1010,8 +1016,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1085,6 +1091,10 @@ msgstr ""
msgid "Read-only object" msgid "Read-only object"
msgstr "" msgstr ""
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "" msgstr ""
@ -1195,11 +1205,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1221,6 +1231,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1292,7 +1303,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "" msgstr ""
@ -2163,6 +2174,11 @@ msgstr ""
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "" msgstr ""
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n" "Language-Team: @sommersoft, @MrCertainly\n"
@ -301,6 +301,10 @@ msgstr ""
"Auto-reload be on. Put yer files on USB to weigh anchor, er' bring'er about " "Auto-reload be on. Put yer files on USB to weigh anchor, er' bring'er about "
"t' the REPL t' scuttle.\n" "t' the REPL t' scuttle.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "" msgstr ""
@ -526,6 +530,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -738,6 +743,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1014,8 +1020,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1089,6 +1095,10 @@ msgstr ""
msgid "Read-only object" msgid "Read-only object"
msgstr "" msgstr ""
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "" msgstr ""
@ -1199,11 +1209,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1225,6 +1235,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1296,7 +1307,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "" msgstr ""
@ -2167,6 +2178,11 @@ msgstr ""
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "" msgstr ""
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@ -305,6 +305,10 @@ msgstr ""
"Auto-reload habilitado. Simplemente guarda los archivos via USB para " "Auto-reload habilitado. Simplemente guarda los archivos via USB para "
"ejecutarlos o entra al REPL para desabilitarlos.\n" "ejecutarlos o entra al REPL para desabilitarlos.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Bit clock y word select deben compartir una unidad de reloj" msgstr "Bit clock y word select deben compartir una unidad de reloj"
@ -530,6 +534,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "Rotación de display debe ser en incrementos de 90 grados" msgstr "Rotación de display debe ser en incrementos de 90 grados"
@ -743,6 +748,7 @@ msgid "Function requires lock"
msgstr "La función requiere lock" msgstr "La función requiere lock"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1029,11 +1035,9 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
"Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:% d "
"bppdado"
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
#, fuzzy #, fuzzy
@ -1113,6 +1117,10 @@ msgstr "Sistema de archivos de solo-Lectura"
msgid "Read-only object" msgid "Read-only object"
msgstr "Solo-lectura" msgstr "Solo-lectura"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Canal derecho no soportado" msgstr "Canal derecho no soportado"
@ -1235,11 +1243,11 @@ msgstr "El signo del sample no iguala al del mixer"
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "La altura del Tile debe dividir exacto la altura del bitmap" msgstr "La altura del Tile debe dividir exacto la altura del bitmap"
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1261,6 +1269,7 @@ msgid "Too many display busses"
msgstr "Demasiados buses de pantalla" msgstr "Demasiados buses de pantalla"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Muchos displays" msgstr "Muchos displays"
@ -1332,7 +1341,7 @@ msgstr "Número incomparable de elementos en RHS (%d esperado,%d obtenido)"
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Baudrate no soportado" msgstr "Baudrate no soportado"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "tipo de bitmap no soportado" msgstr "tipo de bitmap no soportado"
@ -2222,6 +2231,11 @@ msgstr "no se ha encontrado ningún enlace para nonlocal"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "ningún módulo se llama '%q'" msgstr "ningún módulo se llama '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "no hay tal atributo" msgstr "no hay tal atributo"
@ -2887,6 +2901,13 @@ msgstr "paso cero"
#~ msgid "Only bit maps of 8 bit color or less are supported" #~ msgid "Only bit maps of 8 bit color or less are supported"
#~ msgstr "Solo se admiten bit maps de color de 8 bits o menos" #~ msgstr "Solo se admiten bit maps de color de 8 bits o menos"
#~ msgid ""
#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d "
#~ "bpp given"
#~ msgstr ""
#~ "Solo se admiten BMP monocromos, indexados de 8bpp y 16bpp o superiores:"
#~ "% d bppdado"
#~ msgid "Only true color (24 bpp or higher) BMP supported %x" #~ msgid "Only true color (24 bpp or higher) BMP supported %x"
#~ msgstr "Solo color verdadero (24 bpp o superior) BMP admitido %x" #~ msgstr "Solo color verdadero (24 bpp o superior) BMP admitido %x"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n" "Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n" "Language-Team: fil\n"
@ -303,6 +303,10 @@ msgstr ""
"Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB " "Ang awtomatikong pag re-reload ay ON. i-save lamang ang mga files sa USB "
"para patakbuhin sila o pasukin ang REPL para i-disable ito.\n" "para patakbuhin sila o pasukin ang REPL para i-disable ito.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Ang bit clock at word select dapat makibahagi sa isang clock unit" msgstr "Ang bit clock at word select dapat makibahagi sa isang clock unit"
@ -534,6 +538,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -752,6 +757,7 @@ msgid "Function requires lock"
msgstr "Function nangangailangan ng lock" msgstr "Function nangangailangan ng lock"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1037,8 +1043,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1118,6 +1124,10 @@ msgstr "Basahin-lamang mode"
msgid "Read-only object" msgid "Read-only object"
msgstr "Basahin-lamang" msgstr "Basahin-lamang"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Hindi supportado ang kanang channel" msgstr "Hindi supportado ang kanang channel"
@ -1238,11 +1248,11 @@ msgstr "Ang signedness ng sample hindi tugma sa mixer"
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1264,6 +1274,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1336,7 +1347,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Hindi supportadong baudrate" msgstr "Hindi supportadong baudrate"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Hindi supportadong tipo ng bitmap" msgstr "Hindi supportadong tipo ng bitmap"
@ -2234,6 +2245,11 @@ msgstr "no binding para sa nonlocal, nahanap"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "walang module na '%q'" msgstr "walang module na '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "walang ganoon na attribute" msgstr "walang ganoon na attribute"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.1\n" "Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n" "Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n" "Language-Team: fr\n"
@ -308,6 +308,10 @@ msgstr ""
"Auto-chargement activé. Copiez simplement les fichiers en USB pour les " "Auto-chargement activé. Copiez simplement les fichiers en USB pour les "
"lancer ou entrez sur REPL pour le désactiver.\n" "lancer ou entrez sur REPL pour le désactiver.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "'bit clock' et 'word select' doivent partager une horloge" msgstr "'bit clock' et 'word select' doivent partager une horloge"
@ -538,6 +542,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés" msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés"
@ -757,6 +762,7 @@ msgid "Function requires lock"
msgstr "La fonction nécessite un verrou" msgstr "La fonction nécessite un verrou"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1049,10 +1055,9 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
"Seul les BMP monochromes, 8bit indexé et 16bit sont supportés: %d bpp fourni"
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
#, fuzzy #, fuzzy
@ -1134,6 +1139,10 @@ msgstr "Système de fichier en lecture seule"
msgid "Read-only object" msgid "Read-only object"
msgstr "Objet en lecture seule" msgstr "Objet en lecture seule"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Canal droit non supporté" msgstr "Canal droit non supporté"
@ -1259,11 +1268,11 @@ msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer"
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image" msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image"
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1285,6 +1294,7 @@ msgid "Too many display busses"
msgstr "Trop de bus d'affichage" msgstr "Trop de bus d'affichage"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Trop d'affichages" msgstr "Trop d'affichages"
@ -1361,7 +1371,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Débit non supporté" msgstr "Débit non supporté"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Type de bus d'affichage non supporté" msgstr "Type de bus d'affichage non supporté"
@ -2268,6 +2278,11 @@ msgstr "pas de lien trouvé pour nonlocal"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "pas de module '%q'" msgstr "pas de module '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "pas de tel attribut" msgstr "pas de tel attribut"
@ -2938,6 +2953,13 @@ msgstr "'step' nul"
#~ msgid "Only bit maps of 8 bit color or less are supported" #~ msgid "Only bit maps of 8 bit color or less are supported"
#~ msgstr "Seules les bitmaps de 8bits par couleur ou moins sont supportées" #~ msgstr "Seules les bitmaps de 8bits par couleur ou moins sont supportées"
#~ msgid ""
#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d "
#~ "bpp given"
#~ msgstr ""
#~ "Seul les BMP monochromes, 8bit indexé et 16bit sont supportés: %d bpp "
#~ "fourni"
#~ msgid "Only true color (24 bpp or higher) BMP supported %x" #~ msgid "Only true color (24 bpp or higher) BMP supported %x"
#~ msgstr "Seul les BMP 24bits ou plus sont supportés %x" #~ msgstr "Seul les BMP 24bits ou plus sont supportés %x"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n" "Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n" "Language-Team: \n"
@ -302,6 +302,10 @@ msgstr ""
"L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL " "L'auto-reload è attivo. Salva i file su USB per eseguirli o entra nel REPL "
"per disabilitarlo.\n" "per disabilitarlo.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "" msgstr ""
@ -534,6 +538,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -751,6 +756,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1037,8 +1043,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1122,6 +1128,10 @@ msgstr "Filesystem in sola lettura"
msgid "Read-only object" msgid "Read-only object"
msgstr "Sola lettura" msgstr "Sola lettura"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Canale destro non supportato" msgstr "Canale destro non supportato"
@ -1237,11 +1247,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1263,6 +1273,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Troppi schermi" msgstr "Troppi schermi"
@ -1335,7 +1346,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "baudrate non supportato" msgstr "baudrate non supportato"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "tipo di bitmap non supportato" msgstr "tipo di bitmap non supportato"
@ -2228,6 +2239,11 @@ msgstr "nessun binding per nonlocal trovato"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "nessun modulo chiamato '%q'" msgstr "nessun modulo chiamato '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "attributo inesistente" msgstr "attributo inesistente"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n" "Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n" "Language-Team: pl\n"
@ -300,6 +300,10 @@ msgstr ""
"Samo-przeładowywanie włączone. Po prostu zapisz pliki przez USB aby je " "Samo-przeładowywanie włączone. Po prostu zapisz pliki przez USB aby je "
"uruchomić, albo wejdź w konsolę aby wyłączyć.\n" "uruchomić, albo wejdź w konsolę aby wyłączyć.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Zegar bitowy i wybór słowa muszą współdzielić jednostkę zegara" msgstr "Zegar bitowy i wybór słowa muszą współdzielić jednostkę zegara"
@ -525,6 +529,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "Wyświetlacz można obracać co 90 stopni" msgstr "Wyświetlacz można obracać co 90 stopni"
@ -737,6 +742,7 @@ msgid "Function requires lock"
msgstr "Funkcja wymaga blokady" msgstr "Funkcja wymaga blokady"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1020,9 +1026,9 @@ msgstr "Wspierane są tylko nieskompresowane pliki BMP: wielkość nagłówka %d
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "Wspierane są tylko pliki BMP czarno-białe, 8bpp i 16bpp: %d bpp " msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Only slices with step=1 (aka None) are supported" msgid "Only slices with step=1 (aka None) are supported"
@ -1095,6 +1101,10 @@ msgstr "System plików tylko do odczytu"
msgid "Read-only object" msgid "Read-only object"
msgstr "Obiekt tylko do odczytu" msgstr "Obiekt tylko do odczytu"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Prawy kanał jest niewspierany" msgstr "Prawy kanał jest niewspierany"
@ -1215,11 +1225,11 @@ msgstr "Znak nie pasuje do miksera"
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "Wysokość bitmapy musi być wielokrotnością wysokości kafelka" msgstr "Wysokość bitmapy musi być wielokrotnością wysokości kafelka"
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1241,6 +1251,7 @@ msgid "Too many display busses"
msgstr "Zbyt wiele magistrali" msgstr "Zbyt wiele magistrali"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Zbyt wiele wyświetlaczy" msgstr "Zbyt wiele wyświetlaczy"
@ -1312,7 +1323,7 @@ msgstr "Zła liczba obiektów po prawej stronie (oczekiwano %d, jest %d)."
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Zła szybkość transmisji" msgstr "Zła szybkość transmisji"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Zły typ magistrali wyświetlaczy" msgstr "Zły typ magistrali wyświetlaczy"
@ -2188,6 +2199,11 @@ msgstr "brak wiązania dla zmiennej nielokalnej"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "brak modułu o nazwie '%q'" msgstr "brak modułu o nazwie '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "nie ma takiego atrybutu" msgstr "nie ma takiego atrybutu"
@ -2769,6 +2785,11 @@ msgstr "zerowy krok"
#~ msgid "Must be a Group subclass." #~ msgid "Must be a Group subclass."
#~ msgstr "Musi dziedziczyć z Group." #~ msgstr "Musi dziedziczyć z Group."
#~ msgid ""
#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d "
#~ "bpp given"
#~ msgstr "Wspierane są tylko pliki BMP czarno-białe, 8bpp i 16bpp: %d bpp "
#~ msgid "Tile indices must be 0 - 255" #~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie" #~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@ -300,6 +300,10 @@ msgid ""
"disable.\n" "disable.\n"
msgstr "" msgstr ""
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "" msgstr ""
@ -529,6 +533,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "" msgstr ""
@ -746,6 +751,7 @@ msgid "Function requires lock"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1028,8 +1034,8 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
@ -1105,6 +1111,10 @@ msgstr "Sistema de arquivos somente leitura"
msgid "Read-only object" msgid "Read-only object"
msgstr "Somente leitura" msgstr "Somente leitura"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Canal direito não suportado" msgstr "Canal direito não suportado"
@ -1215,11 +1225,11 @@ msgstr ""
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1241,6 +1251,7 @@ msgid "Too many display busses"
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "" msgstr ""
@ -1312,7 +1323,7 @@ msgstr ""
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Taxa de transmissão não suportada" msgstr "Taxa de transmissão não suportada"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
#, fuzzy #, fuzzy
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Taxa de transmissão não suportada" msgstr "Taxa de transmissão não suportada"
@ -2189,6 +2200,11 @@ msgstr ""
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "" msgstr ""
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "" msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: circuitpython-cn\n" "Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-22 15:20-0400\n" "POT-Creation-Date: 2019-08-22 14:29-0700\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n" "Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n" "Language-Team: Chinese Hanyu Pinyin\n"
@ -301,6 +301,10 @@ msgstr ""
"Zìdòng chóngxīn jiāzài. Zhǐ xū tōngguò USB bǎocún wénjiàn lái yùnxíng tāmen " "Zìdòng chóngxīn jiāzài. Zhǐ xū tōngguò USB bǎocún wénjiàn lái yùnxíng tāmen "
"huò shūrù REPL jìnyòng.\n" "huò shūrù REPL jìnyòng.\n"
#: shared-module/displayio/Display.c
msgid "Below minimum frame rate"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit" msgid "Bit clock and word select must share a clock unit"
msgstr "Bǐtè shízhōng hé dānzì xuǎnzé bìxū gòngxiǎng shízhōng dānwèi" msgstr "Bǐtè shízhōng hé dānzì xuǎnzé bìxū gòngxiǎng shízhōng dānwèi"
@ -526,6 +530,7 @@ msgid "Display must have a 16 bit colorspace."
msgstr "" msgstr ""
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Display rotation must be in 90 degree increments" msgid "Display rotation must be in 90 degree increments"
msgstr "Xiǎnshì xuánzhuǎn bìxū 90 dù jiā xīn" msgstr "Xiǎnshì xuánzhuǎn bìxū 90 dù jiā xīn"
@ -738,6 +743,7 @@ msgid "Function requires lock"
msgstr "Hánshù xūyào suǒdìng" msgstr "Hánshù xūyào suǒdìng"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Group already used" msgid "Group already used"
msgstr "" msgstr ""
@ -1023,10 +1029,9 @@ msgstr ""
#: shared-module/displayio/OnDiskBitmap.c #: shared-module/displayio/OnDiskBitmap.c
#, c-format #, c-format
msgid "" msgid ""
"Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp " "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"given" "%d bpp given"
msgstr "" msgstr ""
"Jǐn zhīchí dān sè, suǒyǐn 8bpp hé 16bpp huò gèng dà de BMP: %d bpp tígōng"
#: shared-bindings/_pixelbuf/PixelBuf.c #: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Only slices with step=1 (aka None) are supported" msgid "Only slices with step=1 (aka None) are supported"
@ -1100,6 +1105,10 @@ msgstr "Zhǐ dú wénjiàn xìtǒng"
msgid "Read-only object" msgid "Read-only object"
msgstr "Zhǐ dú duìxiàng" msgstr "Zhǐ dú duìxiàng"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
msgstr ""
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported" msgid "Right channel unsupported"
msgstr "Bù zhīchí yòu tōngdào" msgstr "Bù zhīchí yòu tōngdào"
@ -1222,11 +1231,11 @@ msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi"
msgid "Tile height must exactly divide bitmap height" msgid "Tile height must exactly divide bitmap height"
msgstr "Píng pū gāodù bìxū huàfēn wèi tú gāodù" msgstr "Píng pū gāodù bìxū huàfēn wèi tú gāodù"
#: shared-bindings/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c
msgid "Tile index out of bounds" msgid "Tile index out of bounds"
msgstr "" msgstr ""
#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c #: shared-bindings/displayio/TileGrid.c
msgid "Tile value out of bounds" msgid "Tile value out of bounds"
msgstr "" msgstr ""
@ -1248,6 +1257,7 @@ msgid "Too many display busses"
msgstr "Xiǎnshì zǒngxiàn tài duōle" msgstr "Xiǎnshì zǒngxiàn tài duōle"
#: shared-bindings/displayio/Display.c #: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Too many displays" msgid "Too many displays"
msgstr "Xiǎnshì tài duō" msgstr "Xiǎnshì tài duō"
@ -1319,7 +1329,7 @@ msgstr "RHS (yùqí %d, huòdé %d) shàng wèi pǐpèi de xiàngmù."
msgid "Unsupported baudrate" msgid "Unsupported baudrate"
msgstr "Bù zhīchí de baudrate" msgstr "Bù zhīchí de baudrate"
#: shared-module/displayio/Display.c #: shared-module/displayio/display_core.c
msgid "Unsupported display bus type" msgid "Unsupported display bus type"
msgstr "Bù zhīchí de gōnggòng qìchē lèixíng" msgstr "Bù zhīchí de gōnggòng qìchē lèixíng"
@ -2202,6 +2212,11 @@ msgstr "zhǎo bù dào fēi běndì de bǎng dìng"
msgid "no module named '%q'" msgid "no module named '%q'"
msgstr "méiyǒu mókuài '%q'" msgstr "méiyǒu mókuài '%q'"
#: shared-bindings/displayio/FourWire.c shared-bindings/displayio/I2CDisplay.c
#: shared-bindings/displayio/ParallelBus.c
msgid "no reset pin available"
msgstr ""
#: py/runtime.c shared-bindings/_pixelbuf/__init__.c #: py/runtime.c shared-bindings/_pixelbuf/__init__.c
msgid "no such attribute" msgid "no such attribute"
msgstr "méiyǒu cǐ shǔxìng" msgstr "méiyǒu cǐ shǔxìng"
@ -2798,6 +2813,12 @@ msgstr "líng bù"
#~ msgid "Only bit maps of 8 bit color or less are supported" #~ msgid "Only bit maps of 8 bit color or less are supported"
#~ msgstr "Jǐn zhīchí 8 wèi yánsè huò xiǎoyú" #~ msgstr "Jǐn zhīchí 8 wèi yánsè huò xiǎoyú"
#~ msgid ""
#~ "Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d "
#~ "bpp given"
#~ msgstr ""
#~ "Jǐn zhīchí dān sè, suǒyǐn 8bpp hé 16bpp huò gèng dà de BMP: %d bpp tígōng"
#~ msgid "Tile indices must be 0 - 255" #~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255" #~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255"

10
main.c
View File

@ -253,6 +253,9 @@ bool run_code_py(safe_mode_t safe_mode) {
} }
bool serial_connected_before_animation = false; bool serial_connected_before_animation = false;
#if CIRCUITPY_DISPLAYIO
bool refreshed_epaper_display = false;
#endif
rgb_status_animation_t animation; rgb_status_animation_t animation;
prep_rgb_status_animation(&result, found_main, safe_mode, &animation); prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
while (true) { while (true) {
@ -290,6 +293,13 @@ bool run_code_py(safe_mode_t safe_mode) {
} }
serial_connected_before_animation = serial_connected(); serial_connected_before_animation = serial_connected();
// Refresh the ePaper display if we have one. That way it'll show an error message.
#if CIRCUITPY_DISPLAYIO
if (!refreshed_epaper_display) {
refreshed_epaper_display = maybe_refresh_epaperdisplay();
}
#endif
tick_rgb_status_animation(&animation); tick_rgb_status_animation(&animation);
} }
} }

View File

@ -289,7 +289,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
$(addprefix common-hal/, $(SRC_COMMON_HAL)) $(addprefix common-hal/, $(SRC_COMMON_HAL))
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE)) $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s

View File

@ -60,7 +60,7 @@ void run_background_tasks(void) {
audio_dma_background(); audio_dma_background();
#endif #endif
#if CIRCUITPY_DISPLAYIO #if CIRCUITPY_DISPLAYIO
displayio_refresh_displays(); displayio_background();
#endif #endif
#if CIRCUITPY_NETWORK #if CIRCUITPY_NETWORK

View File

@ -12,5 +12,9 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -12,5 +12,9 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "S25FL064L" EXTERNAL_FLASH_DEVICES = "S25FL064L"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -106,7 +106,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -35,3 +35,7 @@
// USB is always used internally so skip the pin objects for it. // USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1 #define IGNORE_PIN_PA25 1
// SWD is only available on the test pads so skip the pin objects.
#define IGNORE_PIN_PA30 1
#define IGNORE_PIN_PA31 1

View File

@ -13,10 +13,15 @@ EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
# To keep the build small # To keep the build small
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0
# Include these Python libraries in firmware. # Include these Python libraries in firmware.

View File

@ -12,8 +12,10 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C" EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_RTC = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0
CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_RTC = 0

View File

@ -12,5 +12,8 @@ EXTERNAL_FLASH_DEVICE_COUNT = 2
EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_I2CSLAVE = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -0,0 +1,100 @@
/*
* 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.
*/
#include "boards/board.h"
#include "mpconfigboard.h"
#include "hal/include/hal_gpio.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
#include "tick.h"
displayio_fourwire_obj_t board_display_obj;
#define DELAY 0x80
uint8_t display_init_sequence[] = {
0x01, 0 | DELAY, 150, // SWRESET
0x11, 0 | DELAY, 255, // SLPOUT
0x36, 1, 0x00, // _MADCTL bottom to top refresh in vsync aligned order.
0x3a, 1, 0x55, // COLMOD - 16bit color
0x38, 0, // Idle mode off
0x21, 0, // _INVON
0x13, 0, // _NORON
0x29, 0 | DELAY, 255 // _DISPON
};
void board_init(void) {
busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus;
common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL);
common_hal_busio_spi_never_reset(spi);
displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
common_hal_displayio_fourwire_construct(bus,
spi,
&pin_PA07, // TFT_DC Command or data
&pin_PA06, // TFT_CS Chip select
&pin_PA04, // TFT_RST Reset
60000000);
displayio_display_obj_t* display = &displays[0].display;
display->base.type = &displayio_display_type;
common_hal_displayio_display_construct(display,
bus,
240, // Width (after rotation)
240, // Height (after rotation)
0, // column start
0, // row start
180, // rotation
16, // Color depth
false, // Grayscale
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
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
0x37, // set vertical scroll command
display_init_sequence,
sizeof(display_init_sequence),
&pin_PA23, // backlight pin
NO_BRIGHTNESS_COMMAND,
1.0f, // brightness (ignored)
true, // auto_brightness
false, // single_byte_bounds
false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}

View File

@ -0,0 +1,29 @@
#define MICROPY_HW_BOARD_NAME "Adafruit Monster M4SK"
#define MICROPY_HW_MCU_NAME "samd51j19"
#define CIRCUITPY_MCU_FAMILY samd51
#define MICROPY_HW_LED_STATUS (&pin_PA27)
// These are pins not to reset.
// QSPI Data pins
#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
// DotStar pins, QSPI CS, and QSPI SCK
#define MICROPY_PORT_B (PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
#define AUTORESET_DELAY_MS 500
// If you change this, then make sure to update the linker scripts as well to
// make sure you don't overwrite code
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
#define DEFAULT_I2C_BUS_SCL (&pin_PA01)
#define DEFAULT_I2C_BUS_SDA (&pin_PA00)
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1

View File

@ -0,0 +1,18 @@
LD_FILE = boards/samd51x19-bootloader-external-flash.ld
USB_VID = 0x239A
USB_PID = 0x8048
USB_PRODUCT = "Monster M4SK"
USB_MANUFACTURER = "Adafruit Industries LLC"
CHIP_VARIANT = SAMD51J19A
CHIP_FAMILY = samd51
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = GD25Q64C
LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOIO = 1
CIRCUITPY_DISPLAYIO = 1
# No touch on SAMD51 yet
CIRCUITPY_TOUCHIO = 0

View File

@ -0,0 +1,48 @@
#include "shared-bindings/board/__init__.h"
#include "boards/board.h"
#include "shared-module/displayio/__init__.h"
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_HEADPHONE_LEFT), MP_ROM_PTR(&pin_PA02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_HEADPHONE_RIGHT), MP_ROM_PTR(&pin_PA05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PB03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_NOSE), MP_ROM_PTR(&pin_PB03) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PB02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA27) },
// I2C
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA22) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_PA14) },
{ MP_ROM_QSTR(MP_QSTR_MICROPHONE_CLOCK), MP_ROM_PTR(&pin_PA16) },
{ MP_ROM_QSTR(MP_QSTR_MICROPHONE_DATA), MP_ROM_PTR(&pin_PA17) },
// Right TFT control pins
{ MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_LITE), MP_ROM_PTR(&pin_PA23) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_MOSI), MP_ROM_PTR(&pin_PA12) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_SCK), MP_ROM_PTR(&pin_PA13) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RIGHT_TFT_RST), MP_ROM_PTR(&pin_PA04) },
{ MP_ROM_QSTR(MP_QSTR_RIGHT_TFT_CS), MP_ROM_PTR(&pin_PA06) },
{ MP_ROM_QSTR(MP_QSTR_RIGHT_TFT_DC), MP_ROM_PTR(&pin_PA07) },
// Left TFT control pins. Some pins are attached through the SeeSaw chip.
{ MP_OBJ_NEW_QSTR(MP_QSTR_LEFT_TFT_MOSI), MP_ROM_PTR(&pin_PB02) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_LEFT_TFT_SCK), MP_ROM_PTR(&pin_PB03) },
{ MP_ROM_QSTR(MP_QSTR_LEFT_TFT_CS), MP_ROM_PTR(&pin_PB23) },
{ MP_ROM_QSTR(MP_QSTR_LEFT_TFT_DC), MP_ROM_PTR(&pin_PB22) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)},
{ MP_ROM_QSTR(MP_QSTR_RIGHT_DISPLAY), MP_ROM_PTR(&displays[0].display)}
};
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);

View File

@ -108,7 +108,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -86,7 +86,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -108,7 +108,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -86,7 +86,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -98,7 +98,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -118,7 +118,9 @@ void board_init(void) {
1.0f, // brightness (ignored) 1.0f, // brightness (ignored)
true, // auto_brightness true, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data_as_commands false, // data_as_commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -12,5 +12,9 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JV_IQ" EXTERNAL_FLASH_DEVICES = "W25Q16JV_IQ"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CSLAVE = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -12,5 +12,8 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q32FV" EXTERNAL_FLASH_DEVICES = "W25Q32FV"
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_I2CSLAVE = 0
CFLAGS_INLINE_LIMIT = 60 CFLAGS_INLINE_LIMIT = 60
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -12,4 +12,8 @@ EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = W25Q32BV EXTERNAL_FLASH_DEVICES = W25Q32BV
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
SUPEROPT_GC = 0 SUPEROPT_GC = 0

View File

@ -106,7 +106,9 @@ void board_init(void) {
1.0f, // brightness 1.0f, // brightness
false, // auto_brightness false, // auto_brightness
false, // single_byte_bounds false, // single_byte_bounds
false); // data as commands false, // data as commands
true, // auto_refresh
60); // native_frames_per_second
} }
bool board_requests_safe_mode(void) { bool board_requests_safe_mode(void) {

View File

@ -79,15 +79,13 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
self->write_group = &PORT->Group[write->number / 32]; self->write_group = &PORT->Group[write->number / 32];
self->write_mask = 1 << (write->number % 32); self->write_mask = 1 << (write->number % 32);
self->reset.base.type = &mp_type_NoneType;
if (reset != NULL) { if (reset != NULL) {
self->reset.base.type = &digitalio_digitalinout_type; self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset); common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
never_reset_pin_number(reset->number); never_reset_pin_number(reset->number);
common_hal_displayio_parallelbus_reset(self);
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(4);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
} }
never_reset_pin_number(command->number); never_reset_pin_number(command->number);
@ -111,15 +109,31 @@ void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self)
reset_pin_number(self->reset.pin->number); reset_pin_number(self->reset.pin->number);
} }
bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
if (self->reset.base.type == &mp_type_NoneType) {
return false;
}
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(4);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
return true;
}
bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
return true;
}
bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
return true; return true;
} }
void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->command, !command); common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA);
uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR.reg; uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR.reg;
uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET.reg; uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET.reg;
uint32_t mask = self->write_mask; uint32_t mask = self->write_mask;

View File

@ -192,7 +192,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
$(addprefix common-hal/, $(SRC_COMMON_HAL)) $(addprefix common-hal/, $(SRC_COMMON_HAL))
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE)) $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
SRC_S = supervisor/cpu.s SRC_S = supervisor/cpu.s

View File

@ -56,7 +56,7 @@ void run_background_tasks(void) {
#endif #endif
#if CIRCUITPY_DISPLAYIO #if CIRCUITPY_DISPLAYIO
displayio_refresh_displays(); displayio_background();
#endif #endif
running_background_tasks = false; running_background_tasks = false;

View File

@ -31,6 +31,7 @@
#include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Pin.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "tick.h" #include "tick.h"
@ -70,10 +71,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select);
common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL);
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
self->write.base.type = &digitalio_digitalinout_type; self->write.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->write, write); common_hal_digitalio_digitalinout_construct(&self->write, write);
common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL);
@ -93,11 +90,19 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
} }
self->write_mask = 1 << (write->number % num_pins_in_write_port); self->write_mask = 1 << (write->number % num_pins_in_write_port);
self->reset.base.type = &mp_type_NoneType;
if (reset != NULL) {
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
never_reset_pin_number(reset->number);
common_hal_displayio_parallelbus_reset(self);
}
never_reset_pin_number(command->number); never_reset_pin_number(command->number);
never_reset_pin_number(chip_select->number); never_reset_pin_number(chip_select->number);
never_reset_pin_number(write->number); never_reset_pin_number(write->number);
never_reset_pin_number(read->number); never_reset_pin_number(read->number);
never_reset_pin_number(reset->number);
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
never_reset_pin_number(data_pin + i); never_reset_pin_number(data_pin + i);
} }
@ -115,15 +120,32 @@ void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self)
reset_pin_number(self->reset.pin->number); reset_pin_number(self->reset.pin->number);
} }
bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
if (self->reset.base.type == &mp_type_NoneType) {
return false;
}
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(4);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
return true;
}
bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
return true;
}
bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
return true; return true;
} }
void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { // This ignores chip_select behaviour because data is clocked in by the write line toggling.
void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->command, !command); common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA);
uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR; uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR;
uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET; uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET;
uint32_t mask = self->write_mask; uint32_t mask = self->write_mask;

View File

@ -216,7 +216,8 @@ SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
$(addprefix common-hal/, $(SRC_COMMON_HAL)) $(addprefix common-hal/, $(SRC_COMMON_HAL))
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE)) $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
$(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))

View File

@ -49,7 +49,7 @@ void run_background_tasks(void) {
//usb_background(); //usb_background();
#if CIRCUITPY_DISPLAYIO #if CIRCUITPY_DISPLAYIO
displayio_refresh_displays(); displayio_background();
#endif #endif
running_background_tasks = false; running_background_tasks = false;

View File

@ -320,6 +320,7 @@ SRC_SHARED_MODULE_ALL = \
displayio/Bitmap.c \ displayio/Bitmap.c \
displayio/ColorConverter.c \ displayio/ColorConverter.c \
displayio/Display.c \ displayio/Display.c \
displayio/EPaperDisplay.c \
displayio/FourWire.c \ displayio/FourWire.c \
displayio/Group.c \ displayio/Group.c \
displayio/I2CDisplay.c \ displayio/I2CDisplay.c \
@ -363,6 +364,12 @@ SRC_SHARED_MODULE_ALL += \
touchio/__init__.c touchio/__init__.c
endif endif
# All possible sources are listed here, and are filtered by SRC_PATTERNS.
SRC_SHARED_MODULE_INTERNAL = \
$(filter $(SRC_PATTERNS), \
displayio/display_core.c \
)
ifeq ($(INTERNAL_LIBM),1) ifeq ($(INTERNAL_LIBM),1)
SRC_LIBM = \ SRC_LIBM = \
$(addprefix lib/,\ $(addprefix lib/,\

View File

@ -307,7 +307,7 @@ extern const struct _mp_obj_module_t terminalio_module;
#define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module },
#define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, #define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module },
#define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, #define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module },
#define CIRCUITPY_DISPLAY_LIMIT (3) #define CIRCUITPY_DISPLAY_LIMIT (1)
#else #else
#define DISPLAYIO_MODULE #define DISPLAYIO_MODULE
#define FONTIO_MODULE #define FONTIO_MODULE

View File

@ -30,6 +30,7 @@
#include "shared-bindings/busio/SPI.h" #include "shared-bindings/busio/SPI.h"
#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Display.h"
#include "shared-module/_stage/__init__.h" #include "shared-module/_stage/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "Layer.h" #include "Layer.h"
#include "Text.h" #include "Text.h"
@ -95,7 +96,8 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
scale = mp_obj_get_int(args[7]); scale = mp_obj_get_int(args[7]);
} }
while (!displayio_display_begin_transaction(display)) { // TODO: Everything below should be in shared-module because it's not argument parsing.
while (!displayio_display_core_begin_transaction(&display->core)) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
displayio_area_t area; displayio_area_t area;
@ -103,12 +105,12 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
area.y1 = y0; area.y1 = y0;
area.x2 = x1; area.x2 = x1;
area.y2 = y1; area.y2 = y1;
displayio_display_set_region_to_update(display, &area); displayio_display_core_set_region_to_update(&display->core, display->set_column_command, display->set_row_command, NO_COMMAND, NO_COMMAND, display->data_as_commands, false, &area);
display->send(display->bus, true, &display->write_ram_command, 1); display->core.send(display->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &display->write_ram_command, 1);
render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size,
display, scale); display, scale);
displayio_display_end_transaction(display); displayio_display_core_end_transaction(&display->core);
return mp_const_none; return mp_const_none;
} }

View File

@ -51,7 +51,7 @@
//| Most people should not use this class directly. Use a specific display driver instead that will //| Most people should not use this class directly. Use a specific display driver instead that will
//| contain the initialization sequence at minimum. //| contain the initialization sequence at minimum.
//| //|
//| .. class:: Display(display_bus, init_sequence, *, 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, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False) //| .. class:: Display(display_bus, init_sequence, *, 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, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False, auto_refresh=True, native_frames_per_second=60)
//| //|
//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). //| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
//| //|
@ -102,9 +102,11 @@
//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. //| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism.
//| :param bool single_byte_bounds: Display column and row commands use single bytes //| :param bool single_byte_bounds: Display column and row commands use single bytes
//| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this. //| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this.
//| :param bool auto_refresh: Automatically refresh the screen
//| :param int native_frames_per_second: Number of display refreshes per second that occur with the given init_sequence.
//| //|
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) { 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 }; 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 };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
@ -128,6 +130,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
{ MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_data_as_commands, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_data_as_commands, 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_arg_val_t args[MP_ARRAY_SIZE(allowed_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_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@ -178,7 +182,9 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
brightness, brightness,
args[ARG_auto_brightness].u_bool, args[ARG_auto_brightness].u_bool,
args[ARG_single_byte_bounds].u_bool, args[ARG_single_byte_bounds].u_bool,
args[ARG_data_as_commands].u_bool args[ARG_data_as_commands].u_bool,
args[ARG_auto_refresh].u_bool,
args[ARG_native_frames_per_second].u_int
); );
return self; return self;
@ -212,27 +218,66 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in)
} }
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
//| .. method:: refresh_soon() //| .. method:: refresh(*, target_frames_per_second=60, minimum_frames_per_second=1)
//| //|
//| Queues up a display refresh that happens in the background. //| 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.
//| //|
STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) { //| 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 displayio_display_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);
displayio_display_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_displayio_display_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame));
}
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_refresh_obj, 1, displayio_display_obj_refresh);
//| .. attribute:: auto_refresh
//|
//| True when the display is refreshed automatically.
//|
STATIC mp_obj_t displayio_display_obj_get_auto_refresh(mp_obj_t self_in) {
displayio_display_obj_t *self = native_display(self_in); displayio_display_obj_t *self = native_display(self_in);
common_hal_displayio_display_refresh_soon(self); return mp_obj_new_bool(common_hal_displayio_display_get_auto_refresh(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_refresh_obj, displayio_display_obj_get_auto_refresh);
STATIC mp_obj_t displayio_display_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) {
displayio_display_obj_t *self = native_display(self_in);
common_hal_displayio_display_set_auto_refresh(self, mp_obj_is_true(auto_refresh));
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_refresh_soon_obj, displayio_display_obj_refresh_soon); MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_refresh_obj, displayio_display_obj_set_auto_refresh);
//| .. method:: wait_for_frame() const mp_obj_property_t displayio_display_auto_refresh_obj = {
//| .base.type = &mp_type_property,
//| Waits until the next frame has been transmitted to the display unless the wait count is .proxy = {(mp_obj_t)&displayio_display_get_auto_refresh_obj,
//| behind the rendered frames. In that case, this will return immediately with the wait count. (mp_obj_t)&displayio_display_set_auto_refresh_obj,
//| (mp_obj_t)&mp_const_none_obj},
STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { };
displayio_display_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame);
//| .. attribute:: brightness //| .. attribute:: brightness
//| //|
@ -361,7 +406,7 @@ const mp_obj_property_t displayio_display_rotation_obj = {
//| //|
STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) { STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) {
displayio_display_obj_t *self = native_display(self_in); displayio_display_obj_t *self = native_display(self_in);
return self->bus; return common_hal_displayio_display_get_bus(self);
} }
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_bus_obj, displayio_display_obj_get_bus); MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_bus_obj, displayio_display_obj_get_bus);
@ -397,18 +442,18 @@ STATIC mp_obj_t displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *po
if (bufinfo.typecode != BYTEARRAY_TYPECODE) { if (bufinfo.typecode != BYTEARRAY_TYPECODE) {
mp_raise_ValueError(translate("Buffer is not a bytearray.")); mp_raise_ValueError(translate("Buffer is not a bytearray."));
} }
if (self->colorspace.depth != 16) { if (self->core.colorspace.depth != 16) {
mp_raise_ValueError(translate("Display must have a 16 bit colorspace.")); mp_raise_ValueError(translate("Display must have a 16 bit colorspace."));
} }
displayio_area_t area = { displayio_area_t area = {
.x1 = 0, .x1 = 0,
.y1 = y, .y1 = y,
.x2 = self->width, .x2 = self->core.width,
.y2 = y + 1 .y2 = y + 1
}; };
uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->colorspace.depth; uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth;
uint16_t buffer_size = self->width / pixels_per_word; uint16_t buffer_size = self->core.width / pixels_per_word;
uint16_t pixels_per_buffer = displayio_area_size(&area); uint16_t pixels_per_buffer = displayio_area_size(&area);
if (pixels_per_buffer % pixels_per_word) { if (pixels_per_buffer % pixels_per_word) {
buffer_size += 1; buffer_size += 1;
@ -425,7 +470,7 @@ STATIC mp_obj_t displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *po
mask[k] = 0x00000000; mask[k] = 0x00000000;
} }
displayio_display_fill_area(self, &area, mask, result_buffer); displayio_display_core_fill_area(&self->core, &area, mask, result_buffer);
return result; return result;
} else { } else {
mp_raise_ValueError(translate("Buffer is too small")); mp_raise_ValueError(translate("Buffer is too small"));
@ -433,15 +478,13 @@ STATIC mp_obj_t displayio_display_obj_fill_row(size_t n_args, const mp_obj_t *po
} }
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_fill_row_obj, 1, displayio_display_obj_fill_row); MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_fill_row_obj, 1, displayio_display_obj_fill_row);
STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) }, { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) }, { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&displayio_display_refresh_obj) },
{ MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) },
{ MP_ROM_QSTR(MP_QSTR_fill_row), MP_ROM_PTR(&displayio_display_fill_row_obj) }, { MP_ROM_QSTR(MP_QSTR_fill_row), MP_ROM_PTR(&displayio_display_fill_row_obj) },
{ MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&displayio_display_auto_refresh_obj) },
{ MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) },
{ MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) },

View File

@ -24,8 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H
#include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Pin.h"
@ -45,33 +45,27 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, 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, 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, mp_float_t brightness, bool auto_brightness,
bool single_byte_bounds, bool data_as_commands); bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second);
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); bool common_hal_displayio_display_show(displayio_display_obj_t* self,
displayio_group_t* root_group);
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group); bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame);
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); bool common_hal_displayio_display_get_auto_refresh(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_refresh(displayio_display_obj_t* self, bool auto_refresh);
bool displayio_display_begin_transaction(displayio_display_obj_t* self);
void displayio_display_end_transaction(displayio_display_obj_t* self);
// The second point of the region is exclusive.
void displayio_display_set_region_to_update(displayio_display_obj_t* self, displayio_area_t* area);
bool displayio_display_frame_queued(displayio_display_obj_t* self);
bool displayio_display_refresh_queued(displayio_display_obj_t* self);
void displayio_display_finish_refresh(displayio_display_obj_t* self);
void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length);
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self); uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self);
uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self); uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self);
uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self); uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self);
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self); mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self);
bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness); bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_DISPLAY_H

View File

@ -0,0 +1,313 @@
/*
* This file is part of the Micro Python 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.
*/
#include "shared-bindings/displayio/EPaperDisplay.h"
#include <stdint.h>
#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:: displayio
//|
//| :class:`EPaperDisplay` -- Manage updating an epaper display over a display bus
//| ==============================================================================
//|
//| This initializes an epaper display and connects it into CircuitPython. Unlike other
//| objects in CircuitPython, EPaperDisplay objects live until `displayio.release_displays()`
//| is called. This is done so that CircuitPython can use the display itself.
//|
//| Most people should not use this class directly. Use a specific display driver instead that will
//| contain the startup and shutdown sequences at minimum.
//|
//| .. class:: EPaperDisplay(display_bus, start_sequence, stop_sequence, *, width, height, ram_width, ram_height, colstart=0, rowstart=0, rotation=0, set_column_window_command=None, set_row_window_command=None, single_byte_bounds=False, write_black_ram_command, black_bits_inverted=False, write_color_ram_command=None, color_bits_inverted=False, highlight_color=0x000000, refresh_display_command, refresh_time=40, busy_pin=None, busy_state=True, seconds_per_frame=180, always_toggle_chip_select=False)
//|
//| Create a EPaperDisplay object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
//|
//| The ``start_sequence`` and ``stop_sequence`` are bitpacked to minimize the ram impact. Every
//| command begins with a command byte followed by a byte to determine the parameter count and if
//| a delay is need after. When the top bit of the second byte is 1, the next byte will be the
//| delay time in milliseconds. The remaining 7 bits are the parameter count excluding any delay
//| byte. The third through final bytes are the remaining command parameters. The next byte will
//| begin a new command definition.
//|
//| :param display_bus: The bus that the display is connected to
//| :type display_bus: displayio.FourWire or displayio.ParallelBus
//| :param buffer start_sequence: Byte-packed initialization sequence.
//| :param buffer stop_sequence: Byte-packed initialization sequence.
//| :param int width: Width in pixels
//| :param int height: Height in pixels
//| :param int ram_width: RAM width in pixels
//| :param int ram_height: RAM 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 set_column_window_command: Command used to set the start and end columns to update
//| :param int set_row_window_command: Command used so set the start and end rows to update
//| :param int set_current_column_command: Command used to set the current column location
//| :param int set_current_row_command: Command used to set the current row location
//| :param int write_black_ram_command: Command used to write pixels values into the update region
//| :param bool black_bits_inverted: True if 0 bits are used to show black pixels. Otherwise, 1 means to show black.
//| :param int write_color_ram_command: Command used to write pixels values into the update region
//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color.
//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color.
//| :param int refresh_display_command: Command used to start a display refresh
//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided.
//| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy
//| :param bool busy_state: State of the busy pin when the display is busy
//| :param float seconds_per_frame: Minimum number of seconds between screen refreshes
//| :param bool always_toggle_chip_select: When True, chip select is toggled every byte
//|
STATIC mp_obj_t displayio_epaperdisplay_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_start_sequence, ARG_stop_sequence, ARG_width, ARG_height, ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command, ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted, ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state, ARG_seconds_per_frame, ARG_always_toggle_chip_select };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_start_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_stop_sequence, 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_ram_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, },
{ MP_QSTR_ram_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_set_column_window_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} },
{ MP_QSTR_set_row_window_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} },
{ MP_QSTR_set_current_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} },
{ MP_QSTR_set_current_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_COMMAND} },
{ MP_QSTR_write_black_ram_command, MP_ARG_INT | MP_ARG_REQUIRED },
{ MP_QSTR_black_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
{ MP_QSTR_refresh_display_command, MP_ARG_INT | MP_ARG_REQUIRED },
{ MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} },
{ MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_busy_state, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
{ MP_QSTR_seconds_per_frame, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(180)} },
{ MP_QSTR_always_toggle_chip_select, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
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 display_bus = args[ARG_display_bus].u_obj;
mp_buffer_info_t start_bufinfo;
mp_get_buffer_raise(args[ARG_start_sequence].u_obj, &start_bufinfo, MP_BUFFER_READ);
mp_buffer_info_t stop_bufinfo;
mp_get_buffer_raise(args[ARG_stop_sequence].u_obj, &stop_bufinfo, MP_BUFFER_READ);
mp_obj_t busy_pin_obj = args[ARG_busy_pin].u_obj;
assert_pin(busy_pin_obj, true);
const mcu_pin_obj_t* busy_pin = NULL;
if (busy_pin_obj != NULL && busy_pin_obj != mp_const_none) {
busy_pin = MP_OBJ_TO_PTR(busy_pin_obj);
assert_pin_free(busy_pin);
}
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"));
}
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"));
}
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);
mp_int_t write_color_ram_command = NO_COMMAND;
mp_int_t highlight_color = args[ARG_highlight_color].u_int;
if (args[ARG_write_color_ram_command].u_obj != mp_const_none) {
write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj);
}
self->base.type = &displayio_epaperdisplay_type;
common_hal_displayio_epaperdisplay_construct(
self,
display_bus,
start_bufinfo.buf, start_bufinfo.len, stop_bufinfo.buf, stop_bufinfo.len,
args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation,
args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int,
args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int,
args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, args[ARG_color_bits_inverted].u_bool, highlight_color, args[ARG_refresh_display_command].u_int, refresh_time,
busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, args[ARG_always_toggle_chip_select].u_bool
);
return self;
}
// Helper to ensure we have the native super class instead of a subclass.
static displayio_epaperdisplay_obj_t* native_display(mp_obj_t display_obj) {
mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &displayio_epaperdisplay_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 displayio_epaperdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) {
displayio_epaperdisplay_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_displayio_epaperdisplay_show(self, group);
if (!ok) {
mp_raise_ValueError(translate("Group already used"));
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_epaperdisplay_show_obj, displayio_epaperdisplay_obj_show);
//| .. method:: refresh()
//|
//| Refreshes the display immediately or raises an exception if too soon. Use
//| ``time.sleep(display.time_to_refresh)`` to sleep until a refresh can occur.
//|
STATIC mp_obj_t displayio_epaperdisplay_obj_refresh(mp_obj_t self_in) {
displayio_epaperdisplay_obj_t *self = native_display(self_in);
bool ok = common_hal_displayio_epaperdisplay_refresh(self);
if (!ok) {
mp_raise_RuntimeError(translate("Refresh too soon"));
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_refresh_obj, displayio_epaperdisplay_obj_refresh);
//| .. attribute:: time_to_refresh
//|
//| Time, in fractional seconds, until the ePaper display can be refreshed.
//|
//|
STATIC mp_obj_t displayio_epaperdisplay_obj_get_time_to_refresh(mp_obj_t self_in) {
displayio_epaperdisplay_obj_t *self = native_display(self_in);
return mp_obj_new_float(common_hal_displayio_epaperdisplay_get_time_to_refresh(self) / 1000.0);
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_time_to_refresh_obj, displayio_epaperdisplay_obj_get_time_to_refresh);
const mp_obj_property_t displayio_epaperdisplay_time_to_refresh_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_epaperdisplay_get_time_to_refresh_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: width
//|
//| Gets the width of the display in pixels
//|
//|
STATIC mp_obj_t displayio_epaperdisplay_obj_get_width(mp_obj_t self_in) {
displayio_epaperdisplay_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_width(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_width_obj, displayio_epaperdisplay_obj_get_width);
const mp_obj_property_t displayio_epaperdisplay_width_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_epaperdisplay_get_width_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: height
//|
//| Gets the height of the display in pixels
//|
//|
STATIC mp_obj_t displayio_epaperdisplay_obj_get_height(mp_obj_t self_in) {
displayio_epaperdisplay_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_epaperdisplay_get_height(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_height_obj, displayio_epaperdisplay_obj_get_height);
const mp_obj_property_t displayio_epaperdisplay_height_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_epaperdisplay_get_height_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: bus
//|
//| The bus being used by the display
//|
//|
STATIC mp_obj_t displayio_epaperdisplay_obj_get_bus(mp_obj_t self_in) {
displayio_epaperdisplay_obj_t *self = native_display(self_in);
return common_hal_displayio_epaperdisplay_get_bus(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_epaperdisplay_get_bus_obj, displayio_epaperdisplay_obj_get_bus);
const mp_obj_property_t displayio_epaperdisplay_bus_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&displayio_epaperdisplay_get_bus_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
STATIC const mp_rom_map_elem_t displayio_epaperdisplay_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_epaperdisplay_show_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&displayio_epaperdisplay_refresh_obj) },
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_epaperdisplay_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_epaperdisplay_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_epaperdisplay_bus_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_to_refresh), MP_ROM_PTR(&displayio_epaperdisplay_time_to_refresh_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_epaperdisplay_locals_dict, displayio_epaperdisplay_locals_dict_table);
const mp_obj_type_t displayio_epaperdisplay_type = {
{ &mp_type_type },
.name = MP_QSTR_EPaperDisplay,
.make_new = displayio_epaperdisplay_make_new,
.locals_dict = (mp_obj_dict_t*)&displayio_epaperdisplay_locals_dict,
};

View File

@ -0,0 +1,61 @@
/*
* This file is part of the Micro Python 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_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H
#include "common-hal/microcontroller/Pin.h"
#include "shared-module/displayio/EPaperDisplay.h"
#include "shared-module/displayio/Group.h"
extern const mp_obj_type_t displayio_epaperdisplay_type;
#define DELAY 0x80
#define NO_COMMAND 0x100
void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self,
mp_obj_t bus, uint8_t* start_sequence, uint16_t start_sequence_len, uint8_t* stop_sequence, uint16_t stop_sequence_len,
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 set_column_window_command, uint16_t set_row_window_command,
uint16_t set_current_column_command, uint16_t set_current_row_command,
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time,
const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select);
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self);
bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t* self, displayio_group_t* root_group);
// Returns time in milliseconds.
uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t* self);
uint16_t common_hal_displayio_epaperdisplay_get_width(displayio_epaperdisplay_obj_t* self);
uint16_t common_hal_displayio_epaperdisplay_get_height(displayio_epaperdisplay_obj_t* self);
mp_obj_t common_hal_displayio_epaperdisplay_get_bus(displayio_epaperdisplay_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_EPAPERDISPLAY_H

View File

@ -103,33 +103,63 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_
return self; return self;
} }
//| .. method:: send(command, data) //| .. method:: reset()
//|
//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin
//| is available.
//|
STATIC mp_obj_t displayio_fourwire_obj_reset(mp_obj_t self_in) {
displayio_fourwire_obj_t *self = self_in;
if (!common_hal_displayio_fourwire_reset(self)) {
mp_raise_RuntimeError(translate("no reset pin available"));
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_reset_obj, displayio_fourwire_obj_reset);
//| .. method:: send(command, data, *, toggle_every_byte=False)
//| //|
//| Sends the given command value followed by the full set of data. Display state, such as //| Sends the given command value followed by the full set of data. Display state, such as
//| vertical scroll, set via ``send`` may or may not be reset once the code is done. //| vertical scroll, set via ``send`` may or may not be reset once the code is done.
//| //|
STATIC mp_obj_t displayio_fourwire_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj); enum { ARG_command, ARG_data, ARG_toggle_every_byte };
if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_command, MP_ARG_INT | MP_ARG_REQUIRED },
{ MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_toggle_every_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
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);
mp_int_t command_int = args[ARG_command].u_int;
if (command_int > 255 || command_int < 0) {
mp_raise_ValueError(translate("Command must be an int between 0 and 255")); mp_raise_ValueError(translate("Command must be an int between 0 and 255"));
} }
displayio_fourwire_obj_t *self = pos_args[0];
uint8_t command = command_int; uint8_t command = command_int;
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
// Wait for display bus to be available. // Wait for display bus to be available.
while (!common_hal_displayio_fourwire_begin_transaction(self)) { while (!common_hal_displayio_fourwire_begin_transaction(self)) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
common_hal_displayio_fourwire_send(self, true, &command, 1); display_chip_select_behavior_t chip_select = CHIP_SELECT_UNTOUCHED;
common_hal_displayio_fourwire_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); if (args[ARG_toggle_every_byte].u_bool) {
chip_select = CHIP_SELECT_TOGGLE_EVERY_BYTE;
}
common_hal_displayio_fourwire_send(self, DISPLAY_COMMAND, chip_select, &command, 1);
common_hal_displayio_fourwire_send(self, DISPLAY_DATA, chip_select, ((uint8_t*) bufinfo.buf), bufinfo.len);
common_hal_displayio_fourwire_end_transaction(self); common_hal_displayio_fourwire_end_transaction(self);
return mp_const_none; return mp_const_none;
} }
MP_DEFINE_CONST_FUN_OBJ_3(displayio_fourwire_send_obj, displayio_fourwire_obj_send); MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 3, displayio_fourwire_obj_send);
STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = { STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_fourwire_reset_obj) },
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table);

View File

@ -28,6 +28,8 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H
#include "shared-module/displayio/FourWire.h" #include "shared-module/displayio/FourWire.h"
#include "shared-bindings/displayio/__init__.h"
#include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Pin.h"
#include "shared-module/displayio/Group.h" #include "shared-module/displayio/Group.h"
@ -40,9 +42,12 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self);
bool common_hal_displayio_fourwire_reset(mp_obj_t self);
bool common_hal_displayio_fourwire_bus_free(mp_obj_t self);
bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self);
void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); void common_hal_displayio_fourwire_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length);
void common_hal_displayio_fourwire_end_transaction(mp_obj_t self); void common_hal_displayio_fourwire_end_transaction(mp_obj_t self);

View File

@ -95,6 +95,21 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t
return self; return self;
} }
//| .. method:: reset()
//|
//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin
//| is available.
//|
STATIC mp_obj_t displayio_i2cdisplay_obj_reset(mp_obj_t self_in) {
displayio_i2cdisplay_obj_t *self = self_in;
if (!common_hal_displayio_i2cdisplay_reset(self)) {
mp_raise_RuntimeError(translate("no reset pin available"));
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_i2cdisplay_reset_obj, displayio_i2cdisplay_obj_reset);
//| .. method:: send(command, data) //| .. method:: send(command, data)
//| //|
//| Sends the given command value followed by the full set of data. Display state, such as //| Sends the given command value followed by the full set of data. Display state, such as
@ -116,7 +131,7 @@ STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_ob
uint8_t full_command[bufinfo.len + 1]; uint8_t full_command[bufinfo.len + 1];
full_command[0] = command; full_command[0] = command;
memcpy(full_command + 1, ((uint8_t*) bufinfo.buf), bufinfo.len); memcpy(full_command + 1, ((uint8_t*) bufinfo.buf), bufinfo.len);
common_hal_displayio_i2cdisplay_send(self, true, full_command, bufinfo.len + 1); common_hal_displayio_i2cdisplay_send(self, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, full_command, bufinfo.len + 1);
common_hal_displayio_i2cdisplay_end_transaction(self); common_hal_displayio_i2cdisplay_end_transaction(self);
return mp_const_none; return mp_const_none;
@ -124,6 +139,7 @@ STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_ob
MP_DEFINE_CONST_FUN_OBJ_3(displayio_i2cdisplay_send_obj, displayio_i2cdisplay_obj_send); MP_DEFINE_CONST_FUN_OBJ_3(displayio_i2cdisplay_send_obj, displayio_i2cdisplay_obj_send);
STATIC const mp_rom_map_elem_t displayio_i2cdisplay_locals_dict_table[] = { STATIC const mp_rom_map_elem_t displayio_i2cdisplay_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_i2cdisplay_reset_obj) },
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_i2cdisplay_send_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_i2cdisplay_send_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(displayio_i2cdisplay_locals_dict, displayio_i2cdisplay_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(displayio_i2cdisplay_locals_dict, displayio_i2cdisplay_locals_dict_table);

View File

@ -28,6 +28,8 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
#include "shared-module/displayio/I2CDisplay.h" #include "shared-module/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/__init__.h"
#include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Pin.h"
extern const mp_obj_type_t displayio_i2cdisplay_type; extern const mp_obj_type_t displayio_i2cdisplay_type;
@ -37,9 +39,12 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self); void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self);
bool common_hal_displayio_i2cdisplay_reset(mp_obj_t self);
bool common_hal_displayio_i2cdisplay_bus_free(mp_obj_t self);
bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t self); bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t self);
void common_hal_displayio_i2cdisplay_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); void common_hal_displayio_i2cdisplay_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length);
void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t self); void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t self);

View File

@ -106,6 +106,21 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t
return self; return self;
} }
//| .. method:: reset()
//|
//| Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin
//| is available.
//|
STATIC mp_obj_t displayio_parallelbus_obj_reset(mp_obj_t self_in) {
displayio_parallelbus_obj_t *self = self_in;
if (!common_hal_displayio_parallelbus_reset(self)) {
mp_raise_RuntimeError(translate("no reset pin available"));
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_parallelbus_reset_obj, displayio_parallelbus_obj_reset);
//| .. method:: send(command, data) //| .. method:: send(command, data)
//| //|
//| Sends the given command value followed by the full set of data. Display state, such as //| Sends the given command value followed by the full set of data. Display state, such as
@ -124,8 +139,8 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o
while (!common_hal_displayio_parallelbus_begin_transaction(self)) { while (!common_hal_displayio_parallelbus_begin_transaction(self)) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
common_hal_displayio_parallelbus_send(self, true, &command, 1); common_hal_displayio_parallelbus_send(self, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, &command, 1);
common_hal_displayio_parallelbus_send(self, false, ((uint8_t*) bufinfo.buf), bufinfo.len); common_hal_displayio_parallelbus_send(self, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*) bufinfo.buf), bufinfo.len);
common_hal_displayio_parallelbus_end_transaction(self); common_hal_displayio_parallelbus_end_transaction(self);
return mp_const_none; return mp_const_none;
@ -133,6 +148,7 @@ STATIC mp_obj_t displayio_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_o
MP_DEFINE_CONST_FUN_OBJ_3(displayio_parallelbus_send_obj, displayio_parallelbus_obj_send); MP_DEFINE_CONST_FUN_OBJ_3(displayio_parallelbus_send_obj, displayio_parallelbus_obj_send);
STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = { STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&displayio_parallelbus_reset_obj) },
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table);

View File

@ -28,8 +28,9 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H
#include "common-hal/displayio/ParallelBus.h" #include "common-hal/displayio/ParallelBus.h"
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/microcontroller/Pin.h"
#include "shared-bindings/displayio/__init__.h"
#include "shared-module/displayio/Group.h" #include "shared-module/displayio/Group.h"
extern const mp_obj_type_t displayio_parallelbus_type; extern const mp_obj_type_t displayio_parallelbus_type;
@ -40,9 +41,12 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self);
bool common_hal_displayio_parallelbus_reset(mp_obj_t self);
bool common_hal_displayio_parallelbus_bus_free(mp_obj_t self);
bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self);
void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); void common_hal_displayio_parallelbus_send(mp_obj_t self, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length);
void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self); void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self);

View File

@ -33,6 +33,7 @@
#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Bitmap.h"
#include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/EPaperDisplay.h"
#include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Group.h"
#include "shared-bindings/displayio/I2CDisplay.h" #include "shared-bindings/displayio/I2CDisplay.h"
@ -60,6 +61,7 @@
//| Bitmap //| Bitmap
//| ColorConverter //| ColorConverter
//| Display //| Display
//| EPaperDisplay
//| FourWire //| FourWire
//| Group //| Group
//| I2CDisplay //| I2CDisplay
@ -75,7 +77,7 @@
//| //|
//| Releases any actively used displays so their busses and pins can be used again. This will also //| Releases any actively used displays so their busses and pins can be used again. This will also
//| release the builtin display on boards that have one. You will need to reinitialize it yourself //| release the builtin display on boards that have one. You will need to reinitialize it yourself
//| afterwards. //| afterwards. This may take seconds to complete if an active EPaperDisplay is refreshing.
//| //|
//| Use this once in your code.py if you initialize a display. Place it right before the //| Use this once in your code.py if you initialize a display. Place it right before the
//| initialization so the display is active as long as possible. //| initialization so the display is active as long as possible.
@ -91,6 +93,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) },
{ MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) },
{ MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) },
{ MP_ROM_QSTR(MP_QSTR_EPaperDisplay), MP_ROM_PTR(&displayio_epaperdisplay_type) },
{ MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) },
{ MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) },
{ MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) },

View File

@ -27,6 +27,25 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
#include "py/obj.h"
typedef enum {
DISPLAY_COMMAND,
DISPLAY_DATA
} display_byte_type_t;
typedef enum {
CHIP_SELECT_UNTOUCHED,
CHIP_SELECT_TOGGLE_EVERY_BYTE
} display_chip_select_behavior_t;
typedef bool (*display_bus_bus_reset)(mp_obj_t bus);
typedef bool (*display_bus_bus_free)(mp_obj_t bus);
typedef bool (*display_bus_begin_transaction)(mp_obj_t bus);
typedef void (*display_bus_send)(mp_obj_t bus, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length);
typedef void (*display_bus_end_transaction)(mp_obj_t bus);
void common_hal_displayio_release_displays(void); void common_hal_displayio_release_displays(void);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H

View File

@ -57,7 +57,7 @@ void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
index += 1; index += 1;
// The buffer is full, send it. // The buffer is full, send it.
if (index >= buffer_size) { if (index >= buffer_size) {
display->send(display->bus, false, ((uint8_t*)buffer), display->core.send(display->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*)buffer),
buffer_size * 2); buffer_size * 2);
index = 0; index = 0;
} }
@ -67,6 +67,6 @@ void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
} }
// Send the remaining data. // Send the remaining data.
if (index) { if (index) {
display->send(display->bus, false, ((uint8_t*)buffer), index * 2); display->core.send(display->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t*)buffer), index * 2);
} }
} }

View File

@ -26,6 +26,8 @@
#include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/ColorConverter.h"
#include "py/misc.h"
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) { void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self) {
} }
@ -45,10 +47,71 @@ uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) {
return (r8 * 19) / 255 + (g8 * 182) / 255 + (b8 + 54) / 255; return (r8 * 19) / 255 + (g8 * 182) / 255 + (b8 + 54) / 255;
} }
uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888) {
uint32_t r8 = (color_rgb888 >> 16);
uint32_t g8 = (color_rgb888 >> 8) & 0xff;
uint32_t b8 = color_rgb888 & 0xff;
uint8_t max = MAX(r8, MAX(g8, b8));
uint8_t min = MIN(r8, MIN(g8, b8));
return max - min;
}
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888) {
uint32_t r8 = (color_rgb888 >> 16);
uint32_t g8 = (color_rgb888 >> 8) & 0xff;
uint32_t b8 = color_rgb888 & 0xff;
uint8_t max = MAX(r8, MAX(g8, b8));
uint8_t min = MIN(r8, MIN(g8, b8));
uint8_t c = max - min;
if (c == 0) {
return 0;
}
int32_t hue = 0;
if (max == r8) {
hue = (((int32_t) (g8 - b8) * 40) / c) % 240;
} else if (max == g8) {
hue = (((int32_t) (b8 - r8) + (2 * c)) * 40) / c;
} else if (max == b8) {
hue = (((int32_t) (r8 - g8) + (4 * c)) * 40) / c;
}
if (hue < 0) {
hue += 240;
}
return hue;
}
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* colorspace, uint8_t pixel_hue, uint8_t pixel_luma, uint32_t* color) {
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) {
if (colorspace->grayscale) {
*color = 0;
} else {
*color = 1;
}
} else if (!colorspace->grayscale) {
*color = 0;
}
}
bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) { bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color) {
if (colorspace->depth == 16) { if (colorspace->depth == 16) {
*output_color = displayio_colorconverter_compute_rgb565(input_color); *output_color = displayio_colorconverter_compute_rgb565(input_color);
return true; return true;
} else if (colorspace->tricolor) {
uint8_t luma = displayio_colorconverter_compute_luma(input_color);
*output_color = luma >> (8 - colorspace->depth);
if (displayio_colorconverter_compute_chroma(input_color) <= 16) {
if (!colorspace->grayscale) {
*output_color = 0;
}
return true;
}
uint8_t pixel_hue = displayio_colorconverter_compute_hue(input_color);
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, output_color);
return true;
} else if (colorspace->grayscale && colorspace->depth <= 8) { } else if (colorspace->grayscale && colorspace->depth <= 8) {
uint8_t luma = displayio_colorconverter_compute_luma(input_color); uint8_t luma = displayio_colorconverter_compute_luma(input_color);
*output_color = luma >> (8 - colorspace->depth); *output_color = luma >> (8 - colorspace->depth);

View File

@ -42,5 +42,8 @@ void displayio_colorconverter_finish_refresh(displayio_colorconverter_t *self);
bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color); bool displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color);
uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888); uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888);
uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888);
uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888);
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888);
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t* colorspace, uint8_t pixel_hue, uint8_t pixel_luma, uint32_t* color);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H

View File

@ -33,75 +33,64 @@
#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/usb.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "tick.h" #include "tick.h"
#define DELAY 0x80
void common_hal_displayio_display_construct(displayio_display_obj_t* self, 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, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart,
uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row,
uint8_t set_column_command, uint8_t set_row_command, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, uint8_t set_column_command,
uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll,
const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin,
bool single_byte_bounds, bool data_as_commands) { uint16_t brightness_command, mp_float_t brightness, bool auto_brightness,
self->colorspace.depth = color_depth; bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second) {
self->colorspace.grayscale = grayscale; uint16_t ram_width = 0x100;
self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row; uint16_t ram_height = 0x100;
self->colorspace.bytes_per_cell = bytes_per_cell; if (single_byte_bounds) {
self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte; ram_width = 0xff;
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);
self->set_column_command = set_column_command; self->set_column_command = set_column_command;
self->set_row_command = set_row_command; self->set_row_command = set_row_command;
self->write_ram_command = write_ram_command; self->write_ram_command = write_ram_command;
self->refresh = false;
self->current_group = NULL;
self->colstart = colstart;
self->rowstart = rowstart;
self->brightness_command = brightness_command; self->brightness_command = brightness_command;
self->auto_brightness = auto_brightness; self->auto_brightness = auto_brightness;
self->auto_refresh = auto_refresh;
self->first_manual_refresh = !auto_refresh;
self->data_as_commands = data_as_commands; self->data_as_commands = data_as_commands;
self->single_byte_bounds = single_byte_bounds;
if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { self->native_frames_per_second = native_frames_per_second;
self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; self->native_ms_per_frame = 1000 / native_frames_per_second;
self->send = common_hal_displayio_parallelbus_send;
self->end_transaction = common_hal_displayio_parallelbus_end_transaction;
} else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) {
self->begin_transaction = common_hal_displayio_fourwire_begin_transaction;
self->send = common_hal_displayio_fourwire_send;
self->end_transaction = common_hal_displayio_fourwire_end_transaction;
} else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) {
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;
uint32_t i = 0; uint32_t i = 0;
while (!self->begin_transaction(self->bus)) {
RUN_BACKGROUND_TASKS;
}
while (i < init_sequence_len) { while (i < init_sequence_len) {
uint8_t *cmd = init_sequence + i; uint8_t *cmd = init_sequence + i;
uint8_t data_size = *(cmd + 1); uint8_t data_size = *(cmd + 1);
bool delay = (data_size & DELAY) != 0; bool delay = (data_size & DELAY) != 0;
data_size &= ~DELAY; data_size &= ~DELAY;
uint8_t *data = cmd + 2; uint8_t *data = cmd + 2;
while (!displayio_display_core_begin_transaction(&self->core)) {
RUN_BACKGROUND_TASKS;
}
if (self->data_as_commands) { if (self->data_as_commands) {
uint8_t full_command[data_size + 1]; uint8_t full_command[data_size + 1];
full_command[0] = cmd[0]; full_command[0] = cmd[0];
memcpy(full_command + 1, data, data_size); memcpy(full_command + 1, data, data_size);
self->send(self->bus, true, full_command, data_size + 1); self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, full_command, data_size + 1);
} else { } else {
self->send(self->bus, true, cmd, 1); self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, cmd, 1);
self->send(self->bus, false, data, data_size); self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, data, data_size);
} }
self->core.end_transaction(self->core.bus);
uint16_t delay_length_ms = 10; uint16_t delay_length_ms = 10;
if (delay) { if (delay) {
data_size++; data_size++;
@ -113,33 +102,9 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
common_hal_time_delay_ms(delay_length_ms); common_hal_time_delay_ms(delay_length_ms);
i += 2 + data_size; i += 2 + data_size;
} }
self->end_transaction(self->bus);
supervisor_start_terminal(width, height); supervisor_start_terminal(width, height);
self->width = width;
self->height = height;
self->rotation = rotation % 360;
self->transform.x = 0;
self->transform.y = 0;
self->transform.scale = 1;
self->transform.mirror_x = false;
self->transform.mirror_y = false;
self->transform.transpose_xy = false;
if (rotation == 0 || rotation == 180) {
if (rotation == 180) {
self->transform.mirror_x = true;
self->transform.mirror_y = true;
}
} else {
self->transform.transpose_xy = true;
if (rotation == 270) {
self->transform.mirror_y = true;
} else {
self->transform.mirror_x = true;
}
}
// Always set the backlight type in case we're reusing memory. // Always set the backlight type in case we're reusing memory.
self->backlight_inout.base.type = &mp_type_NoneType; self->backlight_inout.base.type = &mp_type_NoneType;
if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) {
@ -160,107 +125,27 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->current_brightness = -1.0; self->current_brightness = -1.0;
} }
self->area.x1 = 0;
self->area.y1 = 0;
self->area.next = NULL;
self->transform.dx = 1;
self->transform.dy = 1;
if (self->transform.transpose_xy) {
self->area.x2 = height;
self->area.y2 = width;
if (self->transform.mirror_x) {
self->transform.x = height;
self->transform.dx = -1;
}
if (self->transform.mirror_y) {
self->transform.y = width;
self->transform.dy = -1;
}
} else {
self->area.x2 = width;
self->area.y2 = height;
if (self->transform.mirror_x) {
self->transform.x = width;
self->transform.dx = -1;
}
if (self->transform.mirror_y) {
self->transform.y = height;
self->transform.dy = -1;
}
}
// Set the group after initialization otherwise we may send pixels while we delay in // Set the group after initialization otherwise we may send pixels while we delay in
// initialization. // initialization.
common_hal_displayio_display_show(self, &circuitpython_splash); common_hal_displayio_display_show(self, &circuitpython_splash);
} }
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
if (root_group == NULL) { return displayio_display_core_show(&self->core, root_group);
if (!circuitpython_splash.in_group) {
root_group = &circuitpython_splash;
} else if (self->current_group == &circuitpython_splash) {
return false;
}
}
if (root_group == self->current_group) {
return true;
}
if (root_group != NULL && root_group->in_group) {
return false;
}
if (self->current_group != NULL) {
self->current_group->in_group = false;
}
if (root_group != NULL) {
displayio_group_update_transform(root_group, &self->transform);
root_group->in_group = true;
}
self->current_group = root_group;
self->full_refresh = true;
common_hal_displayio_display_refresh_soon(self);
return true;
} }
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) { uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self){
self->refresh = true; return displayio_display_core_get_width(&self->core);
} }
const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self) { uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self){
if (self->full_refresh) { return displayio_display_core_get_height(&self->core);
self->area.next = NULL;
return &self->area;
} else {
return displayio_group_get_refresh_areas(self->current_group, NULL);
}
}
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self) {
uint64_t last_refresh = self->last_refresh;
// Don't try to refresh if we got an exception.
while (last_refresh == self->last_refresh && MP_STATE_VM(mp_pending_exception) == NULL) {
RUN_BACKGROUND_TASKS;
}
return 0;
} }
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) { bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) {
return self->auto_brightness; return self->auto_brightness;
} }
uint16_t common_hal_displayio_display_get_width(displayio_display_obj_t* self){
return self->width;
}
uint16_t common_hal_displayio_display_get_height(displayio_display_obj_t* self){
return self->height;
}
uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self){
return self->rotation;
}
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) { void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) {
self->auto_brightness = auto_brightness; self->auto_brightness = auto_brightness;
} }
@ -279,18 +164,18 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self,
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99);
ok = true; ok = true;
} else if (self->brightness_command != NO_BRIGHTNESS_COMMAND) { } else if (self->brightness_command != NO_BRIGHTNESS_COMMAND) {
ok = self->begin_transaction(self->bus); ok = displayio_display_core_begin_transaction(&self->core);
if (ok) { if (ok) {
if (self->data_as_commands) { if (self->data_as_commands) {
uint8_t set_brightness[2] = {self->brightness_command, (uint8_t) (0xff * brightness)}; uint8_t set_brightness[2] = {self->brightness_command, (uint8_t) (0xff * brightness)};
self->send(self->bus, true, set_brightness, 2); self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, set_brightness, 2);
} else { } else {
uint8_t command = self->brightness_command; uint8_t command = self->brightness_command;
uint8_t hex_brightness = 0xff * brightness; uint8_t hex_brightness = 0xff * brightness;
self->send(self->bus, true, &command, 1); self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &command, 1);
self->send(self->bus, false, &hex_brightness, 1); self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, &hex_brightness, 1);
} }
self->end_transaction(self->bus); displayio_display_core_end_transaction(&self->core);
} }
} }
@ -301,102 +186,165 @@ bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self,
return ok; return ok;
} }
bool displayio_display_begin_transaction(displayio_display_obj_t* self) { mp_obj_t common_hal_displayio_display_get_bus(displayio_display_obj_t* self) {
return self->begin_transaction(self->bus); return self->core.bus;
} }
void displayio_display_end_transaction(displayio_display_obj_t* self) { STATIC const displayio_area_t* _get_refresh_areas(displayio_display_obj_t *self) {
self->end_transaction(self->bus); 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;
} }
void displayio_display_set_region_to_update(displayio_display_obj_t* self, displayio_area_t* area) { STATIC void _send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) {
uint16_t x1 = area->x1;
uint16_t x2 = area->x2;
uint16_t y1 = area->y1;
uint16_t y2 = area->y2;
// Collapse down the dimension where multiple pixels are in a byte.
if (self->colorspace.depth < 8) {
uint8_t pixels_per_byte = 8 / self->colorspace.depth;
if (self->colorspace.pixels_in_byte_share_row) {
x1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
x2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
} else {
y1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
y2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
}
}
// Set column.
uint8_t data[5];
data[0] = self->set_column_command;
uint8_t data_length = 1;
if (!self->data_as_commands) { if (!self->data_as_commands) {
self->send(self->bus, true, data, 1); self->core.send(self->core.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, &self->write_ram_command, 1);
data_length = 0;
} }
if (self->single_byte_bounds) { self->core.send(self->core.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, pixels, length);
data[data_length++] = x1 + self->colstart;
data[data_length++] = x2 - 1 + self->colstart;
} else {
x1 += self->colstart;
x2 += self->colstart - 1;
data[data_length++] = x1 >> 8;
data[data_length++] = x1 & 0xff;
data[data_length++] = x2 >> 8;
data[data_length++] = x2 & 0xff;
}
self->send(self->bus, self->data_as_commands, data, data_length);
// Set row.
data[0] = self->set_row_command;
data_length = 1;
if (!self->data_as_commands) {
self->send(self->bus, true, data, 1);
data_length = 0;
}
if (self->single_byte_bounds) {
data[data_length++] = y1 + self->rowstart;
data[data_length++] = y2 - 1 + self->rowstart;
} else {
y1 += self->rowstart;
y2 += self->rowstart - 1;
data[data_length++] = y1 >> 8;
data[data_length++] = y1 & 0xff;
data[data_length++] = y2 >> 8;
data[data_length++] = y2 & 0xff;
}
self->send(self->bus, self->data_as_commands, data, data_length);
} }
void displayio_display_start_refresh(displayio_display_obj_t* self) { STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t* area) {
self->last_refresh = ticks_ms; uint16_t buffer_size = 128; // In uint32_ts
}
bool displayio_display_frame_queued(displayio_display_obj_t* self) { displayio_area_t clipped;
if (self->current_group == NULL) { // 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;
displayio_display_core_set_region_to_update(&self->core, self->set_column_command, self->set_row_command, NO_COMMAND, NO_COMMAND, self->data_as_commands, false, &subrectangle);
uint16_t subrectangle_size_bytes;
if (self->core.colorspace.depth >= 8) {
subrectangle_size_bytes = displayio_area_size(&subrectangle) * (self->core.colorspace.depth / 8);
} else {
subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / self->core.colorspace.depth);
}
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);
// Can't acquire display bus; skip the rest of the data.
if (!displayio_display_core_bus_free(&self->core)) {
return false; return false;
} }
// Refresh at ~60 fps.
return (ticks_ms - self->last_refresh) > 16;
}
void displayio_display_finish_refresh(displayio_display_obj_t* self) { displayio_display_core_begin_transaction(&self->core);
if (self->current_group != NULL) { _send_pixels(self, (uint8_t*) buffer, subrectangle_size_bytes);
displayio_group_finish_refresh(self->current_group); displayio_display_core_end_transaction(&self->core);
// TODO(tannewt): Make refresh displays faster so we don't starve other
// background tasks.
usb_background();
} }
self->refresh = false; return true;
self->full_refresh = false;
self->last_refresh = ticks_ms;
} }
void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) { STATIC void _refresh_display(displayio_display_obj_t* self) {
if (!self->data_as_commands) { if (!displayio_display_core_bus_free(&self->core)) {
self->send(self->bus, true, &self->write_ram_command, 1); // Can't acquire display bus; skip updating this display. Try next display.
return;
} }
self->send(self->bus, false, pixels, length); displayio_display_core_start_refresh(&self->core);
const displayio_area_t* current_area = _get_refresh_areas(self);
while (current_area != NULL) {
_refresh_area(self, current_area);
current_area = current_area->next;
}
displayio_display_core_finish_refresh(&self->core);
} }
void displayio_display_update_backlight(displayio_display_obj_t* self) { uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self){
return self->core.rotation;
}
bool common_hal_displayio_display_refresh(displayio_display_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 = ticks_ms;
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 (ticks_ms - self->last_refresh_call < remaining_time) {
RUN_BACKGROUND_TASKS;
}
}
self->first_manual_refresh = false;
_refresh_display(self);
return true;
}
bool common_hal_displayio_display_get_auto_refresh(displayio_display_obj_t* self) {
return self->auto_refresh;
}
void common_hal_displayio_display_set_auto_refresh(displayio_display_obj_t* self,
bool auto_refresh) {
self->first_manual_refresh = !auto_refresh;
self->auto_refresh = auto_refresh;
}
STATIC void _update_backlight(displayio_display_obj_t* self) {
if (!self->auto_brightness || self->updating_backlight) { if (!self->auto_brightness || self->updating_backlight) {
return; return;
} }
@ -410,11 +358,16 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) {
self->last_backlight_refresh = ticks_ms; self->last_backlight_refresh = ticks_ms;
} }
void release_display(displayio_display_obj_t* self) { void displayio_display_background(displayio_display_obj_t* self) {
if (self->current_group != NULL) { _update_backlight(self);
self->current_group->in_group = false;
}
if (self->auto_refresh && (ticks_ms - self->core.last_refresh) > self->native_ms_per_frame) {
_refresh_display(self);
}
}
void release_display(displayio_display_obj_t* self) {
release_display_core(&self->core);
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm);
common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); common_hal_pulseio_pwmout_deinit(&self->backlight_pwm);
@ -423,34 +376,12 @@ void release_display(displayio_display_obj_t* self) {
} }
} }
bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { void reset_display(displayio_display_obj_t* self) {
return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer); self->auto_refresh = true;
self->auto_brightness = true;
common_hal_displayio_display_show(self, NULL);
} }
bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped) { void displayio_display_collect_ptrs(displayio_display_obj_t* self) {
bool overlaps = displayio_area_compute_overlap(&self->area, area, clipped); displayio_display_core_collect_ptrs(&self->core);
if (!overlaps) {
return false;
}
// Expand the area if we have multiple pixels per byte and we need to byte
// align the bounds.
if (self->colorspace.depth < 8) {
uint8_t pixels_per_byte = 8 / self->colorspace.depth * self->colorspace.bytes_per_cell;
if (self->colorspace.pixels_in_byte_share_row) {
if (clipped->x1 % pixels_per_byte != 0) {
clipped->x1 -= clipped->x1 % pixels_per_byte;
}
if (clipped->x2 % pixels_per_byte != 0) {
clipped->x2 += pixels_per_byte - clipped->x2 % pixels_per_byte;
}
} else {
if (clipped->y1 % pixels_per_byte != 0) {
clipped->y1 -= clipped->y1 % pixels_per_byte;
}
if (clipped->y2 % pixels_per_byte != 0) {
clipped->y2 += pixels_per_byte - clipped->y2 % pixels_per_byte;
}
}
}
return true;
} }

View File

@ -32,50 +32,35 @@
#include "shared-bindings/pulseio/PWMOut.h" #include "shared-bindings/pulseio/PWMOut.h"
#include "shared-module/displayio/area.h" #include "shared-module/displayio/area.h"
#include "shared-module/displayio/display_core.h"
typedef bool (*display_bus_begin_transaction)(mp_obj_t bus);
typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length);
typedef void (*display_bus_end_transaction)(mp_obj_t bus);
typedef struct { typedef struct {
mp_obj_base_t base; mp_obj_base_t base;
mp_obj_t bus; displayio_display_core_t core;
displayio_group_t *current_group;
uint64_t last_refresh;
display_bus_begin_transaction begin_transaction;
display_bus_send send;
display_bus_end_transaction end_transaction;
union { union {
digitalio_digitalinout_obj_t backlight_inout; digitalio_digitalinout_obj_t backlight_inout;
pulseio_pwmout_obj_t backlight_pwm; pulseio_pwmout_obj_t backlight_pwm;
}; };
uint64_t last_backlight_refresh; uint64_t last_backlight_refresh;
displayio_buffer_transform_t transform; uint64_t last_refresh_call;
displayio_area_t area;
mp_float_t current_brightness; mp_float_t current_brightness;
uint16_t width;
uint16_t height;
uint16_t rotation;
_displayio_colorspace_t colorspace;
int16_t colstart;
int16_t rowstart;
uint16_t brightness_command; uint16_t brightness_command;
uint16_t native_frames_per_second;
uint16_t native_ms_per_frame;
uint8_t set_column_command; uint8_t set_column_command;
uint8_t set_row_command; uint8_t set_row_command;
uint8_t write_ram_command; uint8_t write_ram_command;
bool refresh; bool auto_refresh;
bool single_byte_bounds; bool first_manual_refresh;
bool data_as_commands; bool data_as_commands;
bool auto_brightness; bool auto_brightness;
bool updating_backlight; bool updating_backlight;
bool full_refresh; // New group means we need to refresh the whole display.
} displayio_display_obj_t; } displayio_display_obj_t;
void displayio_display_start_refresh(displayio_display_obj_t* self); void displayio_display_background(displayio_display_obj_t* self);
const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self);
bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
void displayio_display_update_backlight(displayio_display_obj_t* self);
bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped);
void release_display(displayio_display_obj_t* self); void release_display(displayio_display_obj_t* self);
void reset_display(displayio_display_obj_t* self);
void displayio_display_collect_ptrs(displayio_display_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H

View File

@ -0,0 +1,385 @@
/*
* 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.
*/
#include "shared-bindings/displayio/EPaperDisplay.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/ParallelBus.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
#include "supervisor/usb.h"
#include <stdint.h>
#include <string.h>
#include "tick.h"
void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self,
mp_obj_t bus, uint8_t* start_sequence, uint16_t start_sequence_len, uint8_t* stop_sequence, uint16_t stop_sequence_len,
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 set_column_window_command, uint16_t set_row_window_command,
uint16_t set_current_column_command, uint16_t set_current_row_command,
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time,
const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select) {
if (highlight_color != 0x000000) {
self->core.colorspace.tricolor = true;
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
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);
self->set_column_window_command = set_column_window_command;
self->set_row_window_command = set_row_window_command;
self->set_current_column_command = set_current_column_command;
self->set_current_row_command = set_current_row_command;
self->write_black_ram_command = write_black_ram_command;
self->black_bits_inverted = black_bits_inverted;
self->write_color_ram_command = write_color_ram_command;
self->color_bits_inverted = color_bits_inverted;
self->refresh_display_command = refresh_display_command;
self->refresh_time = refresh_time * 1000;
self->busy_state = busy_state;
self->refreshing = false;
self->milliseconds_per_frame = seconds_per_frame * 1000;
self->chip_select = chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED;
self->start_sequence = start_sequence;
self->start_sequence_len = start_sequence_len;
self->stop_sequence = stop_sequence;
self->stop_sequence_len = stop_sequence_len;
self->busy.base.type = &mp_type_NoneType;
if (busy_pin != NULL) {
self->busy.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin);
never_reset_pin_number(busy_pin->number);
}
// Clear the color memory if it isn't in use.
if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) {
// TODO: Clear
}
supervisor_start_terminal(width, height);
// Set the group after initialization otherwise we may send pixels while we delay in
// initialization.
common_hal_displayio_epaperdisplay_show(self, &circuitpython_splash);
}
bool common_hal_displayio_epaperdisplay_show(displayio_epaperdisplay_obj_t* self, displayio_group_t* root_group) {
return displayio_display_core_show(&self->core, root_group);
}
const displayio_area_t* displayio_epaperdisplay_get_refresh_areas(displayio_epaperdisplay_obj_t *self) {
if (self->core.full_refresh) {
self->core.area.next = NULL;
return &self->core.area;
}
const displayio_area_t* first_area = NULL;
if (self->core.current_group != NULL) {
first_area = displayio_group_get_refresh_areas(self->core.current_group, NULL);
}
if (first_area != NULL && self->set_row_window_command == NO_COMMAND) {
self->core.area.next = NULL;
return &self->core.area;
}
return first_area;
}
uint16_t common_hal_displayio_epaperdisplay_get_width(displayio_epaperdisplay_obj_t* self){
return displayio_display_core_get_width(&self->core);
}
uint16_t common_hal_displayio_epaperdisplay_get_height(displayio_epaperdisplay_obj_t* self){
return displayio_display_core_get_height(&self->core);
}
STATIC void wait_for_busy(displayio_epaperdisplay_obj_t* self) {
if (self->busy.base.type == &mp_type_NoneType) {
return;
}
while (common_hal_digitalio_digitalinout_get_value(&self->busy) == self->busy_state) {
RUN_BACKGROUND_TASKS;
}
}
STATIC void send_command_sequence(displayio_epaperdisplay_obj_t* self, bool should_wait_for_busy, uint8_t* sequence, uint32_t sequence_len) {
uint32_t i = 0;
while (i < sequence_len) {
uint8_t *cmd = sequence + i;
uint8_t data_size = *(cmd + 1);
bool delay = (data_size & DELAY) != 0;
data_size &= ~DELAY;
uint8_t *data = cmd + 2;
displayio_display_core_begin_transaction(&self->core);
self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, cmd, 1);
self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, data, data_size);
displayio_display_core_end_transaction(&self->core);
uint16_t delay_length_ms = 0;
if (delay) {
data_size++;
delay_length_ms = *(cmd + 1 + data_size);
if (delay_length_ms == 255) {
delay_length_ms = 500;
}
}
common_hal_time_delay_ms(delay_length_ms);
if (should_wait_for_busy) {
wait_for_busy(self);
}
i += 2 + data_size;
}
}
void displayio_epaperdisplay_start_refresh(displayio_epaperdisplay_obj_t* self) {
// run start sequence
self->core.bus_reset(self->core.bus);
send_command_sequence(self, true, self->start_sequence, self->start_sequence_len);
displayio_display_core_start_refresh(&self->core);
}
uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaperdisplay_obj_t* self) {
if (self->core.last_refresh == 0) {
return 0;
}
// Refresh at seconds per frame rate.
uint32_t elapsed_time = ticks_ms - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) {
return 0;
}
return self->milliseconds_per_frame - elapsed_time;
}
void displayio_epaperdisplay_finish_refresh(displayio_epaperdisplay_obj_t* self) {
// Actually refresh the display now that all pixel RAM has been updated.
displayio_display_core_begin_transaction(&self->core);
self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &self->refresh_display_command, 1);
displayio_display_core_end_transaction(&self->core);
self->refreshing = true;
displayio_display_core_finish_refresh(&self->core);
}
mp_obj_t common_hal_displayio_epaperdisplay_get_bus(displayio_epaperdisplay_obj_t* self) {
return self->core.bus;
}
bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_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;
}
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];
volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1;
uint32_t mask[mask_length];
uint8_t passes = 1;
if (self->core.colorspace.tricolor) {
passes = 2;
}
for (uint8_t pass = 0; pass < passes; pass++) {
uint16_t remaining_rows = displayio_area_height(&clipped);
if (self->set_row_window_command != NO_COMMAND) {
displayio_display_core_set_region_to_update(&self->core, self->set_column_window_command, self->set_row_window_command, self->set_current_column_command, self->set_current_row_command, false, self->chip_select, &clipped);
}
uint8_t write_command = self->write_black_ram_command;
if (pass == 1) {
write_command = self->write_color_ram_command;
}
displayio_display_core_begin_transaction(&self->core);
self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1);
displayio_display_core_end_transaction(&self->core);
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;
uint16_t subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / self->core.colorspace.depth);
memset(mask, 0, mask_length * sizeof(mask[0]));
memset(buffer, 0, buffer_size * sizeof(buffer[0]));
self->core.colorspace.grayscale = true;
if (pass == 1) {
self->core.colorspace.grayscale = false;
}
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
// Invert it all.
if ((pass == 1 && self->color_bits_inverted) ||
(pass == 0 && self->black_bits_inverted)) {
for (uint16_t k = 0; k < buffer_size; k++) {
buffer[k] = ~buffer[k];
}
}
if (!displayio_display_core_begin_transaction(&self->core)) {
// Can't acquire display bus; skip the rest of the data. Try next display.
return false;
}
self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, (uint8_t*) buffer, subrectangle_size_bytes);
displayio_display_core_end_transaction(&self->core);
// TODO(tannewt): Make refresh displays faster so we don't starve other
// background tasks.
usb_background();
}
}
return true;
}
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self) {
if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) {
if (common_hal_digitalio_digitalinout_get_value(&self->busy) != self->busy_state) {
self->refreshing = false;
// Run stop sequence but don't wait for busy because busy is set when sleeping.
send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len);
} else {
return false;
}
}
if (self->core.current_group == NULL) {
return true;
}
// Refresh at seconds per frame rate.
if (common_hal_displayio_epaperdisplay_get_time_to_refresh(self) > 0) {
return false;
}
if (!displayio_display_core_bus_free(&self->core)) {
// Can't acquire display bus; skip updating this display. Try next display.
return false;
}
const displayio_area_t* current_area = displayio_epaperdisplay_get_refresh_areas(self);
if (current_area == NULL) {
return true;
}
displayio_epaperdisplay_start_refresh(self);
while (current_area != NULL) {
displayio_epaperdisplay_refresh_area(self, current_area);
current_area = current_area->next;
}
displayio_epaperdisplay_finish_refresh(self);
return true;
}
void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
if (self->refreshing) {
bool refresh_done = false;
if (self->busy.base.type == &digitalio_digitalinout_type) {
bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy);
refresh_done = busy != self->busy_state;
} else {
refresh_done = ticks_ms - self->core.last_refresh > self->refresh_time;
}
if (refresh_done) {
self->refreshing = false;
// Run stop sequence but don't wait for busy because busy is set when sleeping.
send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len);
}
}
}
void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) {
if (self->refreshing) {
wait_for_busy(self);
self->refreshing = false;
// Run stop sequence but don't wait for busy because busy is set when sleeping.
send_command_sequence(self, false, self->stop_sequence, self->stop_sequence_len);
}
release_display_core(&self->core);
if (self->busy.base.type == &digitalio_digitalinout_type) {
common_hal_digitalio_digitalinout_deinit(&self->busy);
}
}
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) {
displayio_display_core_collect_ptrs(&self->core);
}
bool maybe_refresh_epaperdisplay(void) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].epaper_display.base.type != &displayio_epaperdisplay_type ||
displays[i].epaper_display.core.current_group != &circuitpython_splash) {
// Skip regular displays and those not showing the splash.
continue;
}
displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display;
if (common_hal_displayio_epaperdisplay_get_time_to_refresh(display) != 0) {
return false;
}
return common_hal_displayio_epaperdisplay_refresh(display);
}
// Return true if no ePaper displays are available to pretend it was updated.
return true;
}

View File

@ -0,0 +1,68 @@
/*
* 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_EPAPERDISPLAY_H
#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_EPAPERDISPLAY_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;
digitalio_digitalinout_obj_t busy;
uint32_t milliseconds_per_frame;
uint8_t* start_sequence;
uint32_t start_sequence_len;
uint8_t* stop_sequence;
uint32_t stop_sequence_len;
uint16_t refresh_time;
uint16_t set_column_window_command;
uint16_t set_row_window_command;
uint16_t set_current_column_command;
uint16_t set_current_row_command;
uint16_t write_black_ram_command;
uint16_t write_color_ram_command;
uint8_t refresh_display_command;
uint8_t hue;
bool busy_state;
bool black_bits_inverted;
bool color_bits_inverted;
bool refreshing;
display_chip_select_behavior_t chip_select;
} displayio_epaperdisplay_obj_t;
void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self);
void release_epaperdisplay(displayio_epaperdisplay_obj_t* self);
bool maybe_refresh_epaperdisplay(void);
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_EPAPERDISPLAY_H

View File

@ -33,6 +33,7 @@
#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "tick.h" #include "tick.h"
@ -55,15 +56,13 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select);
common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL);
self->reset.base.type = &mp_type_NoneType;
if (reset != NULL) { if (reset != NULL) {
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset); common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
never_reset_pin_number(reset->number); never_reset_pin_number(reset->number);
common_hal_displayio_fourwire_reset(self);
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(10);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
common_hal_mcu_delay_us(10);
} }
never_reset_pin_number(command->number); never_reset_pin_number(command->number);
@ -80,6 +79,27 @@ void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
reset_pin_number(self->reset.pin->number); reset_pin_number(self->reset.pin->number);
} }
bool common_hal_displayio_fourwire_reset(mp_obj_t obj) {
displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj);
if (self->reset.base.type == &mp_type_NoneType) {
return false;
}
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_time_delay_ms(1);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
common_hal_time_delay_ms(1);
return true;
}
bool common_hal_displayio_fourwire_bus_free(mp_obj_t obj) {
displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj);
if (!common_hal_busio_spi_try_lock(self->bus)) {
return false;
}
common_hal_busio_spi_unlock(self->bus);
return true;
}
bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) {
displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj);
if (!common_hal_busio_spi_try_lock(self->bus)) { if (!common_hal_busio_spi_try_lock(self->bus)) {
@ -91,10 +111,10 @@ bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) {
return true; return true;
} }
void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { void common_hal_displayio_fourwire_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->command, !command); common_hal_digitalio_digitalinout_set_value(&self->command, data_type == DISPLAY_DATA);
if (command) { if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE) {
// Toggle chip select after each command byte in case the display driver // Toggle chip select after each command byte in case the display driver
// IC latches commands based on it. // IC latches commands based on it.
for (size_t i = 0; i < data_length; i++) { for (size_t i = 0; i < data_length; i++) {

View File

@ -35,6 +35,7 @@
#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "tick.h" #include "tick.h"
@ -55,14 +56,13 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
self->address = device_address; self->address = device_address;
self->reset.base.type = &mp_type_NoneType;
if (reset != NULL) { if (reset != NULL) {
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset); common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
never_reset_pin_number(reset->number); never_reset_pin_number(reset->number);
common_hal_displayio_i2cdisplay_reset(self);
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(1);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
} }
} }
@ -74,7 +74,19 @@ void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
reset_pin_number(self->reset.pin->number); reset_pin_number(self->reset.pin->number);
} }
bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) { bool common_hal_displayio_i2cdisplay_reset(mp_obj_t obj) {
displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
if (self->reset.base.type == &mp_type_NoneType) {
return false;
}
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
common_hal_mcu_delay_us(4);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
return true;
}
bool common_hal_displayio_i2cdisplay_bus_free(mp_obj_t obj) {
displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
if (!common_hal_busio_i2c_try_lock(self->bus)) { if (!common_hal_busio_i2c_try_lock(self->bus)) {
return false; return false;
@ -82,9 +94,13 @@ bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) {
return true; return true;
} }
void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t obj) {
return common_hal_displayio_i2cdisplay_bus_free(obj);
}
void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, uint8_t *data, uint32_t data_length) {
displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj); displayio_i2cdisplay_obj_t* self = MP_OBJ_TO_PTR(obj);
if (command) { if (data_type == DISPLAY_COMMAND) {
uint8_t command_bytes[2 * data_length]; uint8_t command_bytes[2 * data_length];
for (uint32_t i = 0; i < data_length; i++) { for (uint32_t i = 0; i < data_length; i++) {
command_bytes[2 * i] = 0x80; command_bytes[2 * i] = 0x80;

View File

@ -74,7 +74,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
self->g_bitmask = 0x3e0; self->g_bitmask = 0x3e0;
self->b_bitmask = 0x1f; self->b_bitmask = 0x1f;
} }
} else if ((indexed) && (self->bits_per_pixel != 1)) { } else if (indexed && self->bits_per_pixel != 1) {
uint16_t palette_size = number_of_colors * sizeof(uint32_t); uint16_t palette_size = number_of_colors * sizeof(uint32_t);
uint16_t palette_offset = 0xe + header_size; uint16_t palette_offset = 0xe + header_size;
@ -90,25 +90,24 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
if (palette_bytes_read != palette_size) { if (palette_bytes_read != palette_size) {
mp_raise_ValueError(translate("Unable to read color palette data")); mp_raise_ValueError(translate("Unable to read color palette data"));
} }
} else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) { } else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) {
mp_raise_ValueError_varg(translate("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size); mp_raise_ValueError_varg(translate("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size);
} }
if ((bits_per_pixel == 4 ) || (( bits_per_pixel == 8) && (number_of_colors == 0))) { if (bits_per_pixel == 8 && number_of_colors == 0) {
mp_raise_ValueError_varg(translate("Only monochrome, indexed 8bpp, and 16bpp or greater BMPs supported: %d bpp given"), bits_per_pixel); mp_raise_ValueError_varg(translate("Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: %d bpp given"), bits_per_pixel);
} }
if (self->bits_per_pixel >=8){ uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1;
self->stride = (self->width * (bits_per_pixel / 8)); uint8_t pixels_per_byte = 8 / self->bits_per_pixel;
if (pixels_per_byte == 0){
self->stride = (self->width * bytes_per_pixel);
// Rows are word aligned. // Rows are word aligned.
if (self->stride % 4 != 0) { if (self->stride % 4 != 0) {
self->stride += 4 - self->stride % 4; self->stride += 4 - self->stride % 4;
} }
} else { } else {
uint32_t bit_stride = self->width; uint32_t bit_stride = self->width * self->bits_per_pixel;
if (bit_stride % 32 != 0) { if (bit_stride % 32 != 0) {
bit_stride += 32 - bit_stride % 32; bit_stride += 32 - bit_stride % 32;
} }
@ -126,10 +125,11 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
uint32_t location; uint32_t location;
uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1; uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel /8) : 1;
if (self->bits_per_pixel >= 8){ uint8_t pixels_per_byte = 8 / self->bits_per_pixel;
if (pixels_per_byte == 0){
location = self->data_offset + (self->height - y - 1) * self->stride + x * bytes_per_pixel; location = self->data_offset + (self->height - y - 1) * self->stride + x * bytes_per_pixel;
} else { } else {
location = self->data_offset + (self->height - y - 1) * self->stride + x / 8; location = self->data_offset + (self->height - y - 1) * self->stride + x / pixels_per_byte;
} }
// We don't cache here because the underlying FS caches sectors. // We don't cache here because the underlying FS caches sectors.
f_lseek(&self->file->fp, location); f_lseek(&self->file->fp, location);
@ -141,20 +141,19 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
uint8_t red; uint8_t red;
uint8_t green; uint8_t green;
uint8_t blue; uint8_t blue;
if (bytes_per_pixel == 1) {
uint8_t offset = (x % pixels_per_byte) * self->bits_per_pixel;
uint8_t mask = (1 << self->bits_per_pixel) - 1;
uint8_t index = (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask;
if (self->bits_per_pixel == 1) { if (self->bits_per_pixel == 1) {
uint8_t bit_offset = x%8; if (index == 1) {
tmp = ( pixel_data & (0x80 >> (bit_offset))) >> (7 - bit_offset); return 0xFFFFFF;
if (tmp == 1) {
return 0x00FFFFFF;
} else { } else {
return 0x00000000; return 0x000000;
} }
} else if (bytes_per_pixel == 1) { }
blue = ((self->palette_data[pixel_data] & 0xFF) >> 0); return self->palette_data[index];
red = ((self->palette_data[pixel_data] & 0xFF0000) >> 16);
green = ((self->palette_data[pixel_data] & 0xFF00) >> 8);
tmp = (red << 16 | green << 8 | blue );
return tmp;
} else if (bytes_per_pixel == 2) { } else if (bytes_per_pixel == 2) {
if (self->g_bitmask == 0x07e0) { // 565 if (self->g_bitmask == 0x07e0) { // 565
red =((pixel_data & self->r_bitmask) >>11); red =((pixel_data & self->r_bitmask) >>11);

View File

@ -52,6 +52,10 @@ void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t
self->colors[palette_index].rgb888 = color; self->colors[palette_index].rgb888 = color;
self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color); self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color);
self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color); self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color);
uint8_t chroma = displayio_colorconverter_compute_chroma(color);
self->colors[palette_index].chroma = chroma;
self->colors[palette_index].hue = displayio_colorconverter_compute_hue(color);
self->needs_refresh = true; self->needs_refresh = true;
} }
@ -64,7 +68,19 @@ bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_col
return false; // returns opaque return false; // returns opaque
} }
if (colorspace->grayscale) { if (colorspace->tricolor) {
uint8_t luma = self->colors[palette_index].luma;
*color = luma >> (8 - colorspace->depth);
// Chroma 0 means the color is a gray and has no hue so never color based on it.
if (self->colors[palette_index].chroma <= 16) {
if (!colorspace->grayscale) {
*color = 0;
}
return true;
}
uint8_t pixel_hue = self->colors[palette_index].hue;
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, luma, color);
} else if (colorspace->grayscale) {
*color = self->colors[palette_index].luma >> (8 - colorspace->depth); *color = self->colors[palette_index].luma >> (8 - colorspace->depth);
} else { } else {
*color = self->colors[palette_index].rgb565; *color = self->colors[palette_index].rgb565;

View File

@ -34,17 +34,21 @@
typedef struct { typedef struct {
uint8_t depth; uint8_t depth;
bool grayscale;
bool pixels_in_byte_share_row;
uint8_t bytes_per_cell; uint8_t bytes_per_cell;
uint8_t tricolor_hue;
uint8_t tricolor_luma;
bool grayscale;
bool tricolor;
bool pixels_in_byte_share_row;
bool reverse_pixels_in_byte; bool reverse_pixels_in_byte;
uint8_t hue;
} _displayio_colorspace_t; } _displayio_colorspace_t;
typedef struct { typedef struct {
uint32_t rgb888; uint32_t rgb888;
uint16_t rgb565; uint16_t rgb565;
uint8_t luma; uint8_t luma;
uint8_t hue;
uint8_t chroma;
bool transparent; // This may have additional bits added later for blending. bool transparent; // This may have additional bits added later for blending.
} _displayio_color_t; } _displayio_color_t;

View File

@ -207,7 +207,7 @@ uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint1
void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) { void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) {
if (tile_index >= self->tiles_in_bitmap) { if (tile_index >= self->tiles_in_bitmap) {
mp_raise_ValueError(translate("Tile value out of bounds")); mp_raise_ValueError(translate("Tile index out of bounds"));
} }
uint8_t* tiles = self->tiles; uint8_t* tiles = self->tiles;
if (self->inline_tiles) { if (self->inline_tiles) {
@ -443,6 +443,7 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c
} }
uint8_t shift = (offset % pixels_per_byte) * colorspace->depth; uint8_t shift = (offset % pixels_per_byte) * colorspace->depth;
if (colorspace->reverse_pixels_in_byte) { if (colorspace->reverse_pixels_in_byte) {
// Reverse the shift by subtracting it from the leftmost shift.
shift = (pixels_per_byte - 1) * colorspace->depth - shift; shift = (pixels_per_byte - 1) * colorspace->depth - shift;
} }
((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << shift; ((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << shift;

View File

@ -43,7 +43,7 @@ typedef struct {
uint16_t pixel_width; uint16_t pixel_width;
uint16_t pixel_height; uint16_t pixel_height;
uint16_t bitmap_width_in_tiles;; uint16_t bitmap_width_in_tiles;;
uint8_t tiles_in_bitmap; uint16_t tiles_in_bitmap;
uint16_t width_in_tiles; uint16_t width_in_tiles;
uint16_t height_in_tiles; uint16_t height_in_tiles;
uint16_t tile_width; uint16_t tile_width;

View File

@ -4,7 +4,6 @@
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#include "lib/utils/interrupt_char.h" #include "lib/utils/interrupt_char.h"
#include "py/gc.h"
#include "py/reload.h" #include "py/reload.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "shared-bindings/board/__init__.h" #include "shared-bindings/board/__init__.h"
@ -16,103 +15,13 @@
#include "supervisor/shared/autoreload.h" #include "supervisor/shared/autoreload.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/memory.h" #include "supervisor/memory.h"
#include "supervisor/usb.h"
primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
uint32_t frame_count = 0;
bool refresh_area(displayio_display_obj_t* display, const displayio_area_t* area) { // Check for recursive calls to displayio_background.
uint16_t buffer_size = 128; // In uint32_ts bool displayio_background_in_progress = false;
displayio_area_t clipped; void displayio_background(void) {
// Clip the area to the display by overlapping the areas. If there is no overlap then we're done.
if (!displayio_display_clip_area(display, 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) / display->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 (display->colorspace.depth < 8 && !display->colorspace.pixels_in_byte_share_row) {
uint8_t pixels_per_byte = 8 / display->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];
volatile 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;
displayio_display_begin_transaction(display);
displayio_display_set_region_to_update(display, &subrectangle);
displayio_display_end_transaction(display);
uint16_t subrectangle_size_bytes;
if (display->colorspace.depth >= 8) {
subrectangle_size_bytes = displayio_area_size(&subrectangle) * (display->colorspace.depth / 8);
} else {
subrectangle_size_bytes = displayio_area_size(&subrectangle) / (8 / display->colorspace.depth);
}
for (uint16_t k = 0; k < mask_length; k++) {
mask[k] = 0x00000000;
}
for (uint16_t k = 0; k < buffer_size; k++) {
buffer[k] = 0x00000000;
}
displayio_display_fill_area(display, &subrectangle, mask, buffer);
if (!displayio_display_begin_transaction(display)) {
// Can't acquire display bus; skip the rest of the data. Try next display.
return false;
}
displayio_display_send_pixels(display, (uint8_t*) buffer, subrectangle_size_bytes);
displayio_display_end_transaction(display);
// TODO(tannewt): Make refresh displays faster so we don't starve other
// background tasks.
usb_background();
}
return true;
}
// Check for recursive calls to displayio_refresh_displays.
bool refresh_displays_in_progress = false;
void displayio_refresh_displays(void) {
if (mp_hal_is_interrupted()) { if (mp_hal_is_interrupted()) {
return; return;
} }
@ -121,46 +30,43 @@ void displayio_refresh_displays(void) {
return; return;
} }
if (refresh_displays_in_progress) { if (displayio_background_in_progress) {
// Don't allow recursive calls to this routine. // Don't allow recursive calls to this routine.
return; return;
} }
refresh_displays_in_progress = true; displayio_background_in_progress = true;
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { 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) { if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) {
// Skip null display. // Skip null display.
continue; continue;
} }
displayio_display_obj_t* display = &displays[i].display; if (displays[i].display.base.type == &displayio_display_type) {
displayio_display_update_backlight(display); displayio_display_background(&displays[i].display);
} else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) {
// Time to refresh at specified frame rate? displayio_epaperdisplay_background(&displays[i].epaper_display);
if (!displayio_display_frame_queued(display)) {
// Too soon. Try next display.
continue;
} }
if (!displayio_display_begin_transaction(display)) {
// Can't acquire display bus; skip updating this display. Try next display.
continue;
}
displayio_display_end_transaction(display);
displayio_display_start_refresh(display);
const displayio_area_t* current_area = displayio_display_get_refresh_areas(display);
while (current_area != NULL) {
refresh_area(display, current_area);
current_area = current_area->next;
}
displayio_display_finish_refresh(display);
frame_count++;
} }
// All done. // All done.
refresh_displays_in_progress = false; displayio_background_in_progress = false;
} }
void common_hal_displayio_release_displays(void) { void common_hal_displayio_release_displays(void) {
// Release displays before busses so that they can send any final commands to turn the display
// off properly.
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) {
continue;
} else if (display_type == &displayio_display_type) {
release_display(&displays[i].display);
} else if (display_type == &displayio_epaperdisplay_type) {
release_epaperdisplay(&displays[i].epaper_display);
}
displays[i].display.base.type = &mp_type_NoneType;
}
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type;
if (bus_type == NULL || bus_type == &mp_type_NoneType) { if (bus_type == NULL || bus_type == &mp_type_NoneType) {
@ -174,10 +80,6 @@ void common_hal_displayio_release_displays(void) {
} }
displays[i].fourwire_bus.base.type = &mp_type_NoneType; displays[i].fourwire_bus.base.type = &mp_type_NoneType;
} }
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
release_display(&displays[i].display);
displays[i].display.base.type = &mp_type_NoneType;
}
supervisor_stop_terminal(); supervisor_stop_terminal();
} }
@ -214,7 +116,7 @@ void reset_displays(void) {
((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { ((uint32_t) i2c->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) {
busio_i2c_obj_t* original_i2c = i2c->bus; busio_i2c_obj_t* original_i2c = i2c->bus;
#if BOARD_I2C #if BOARD_I2C
// We don't need to move original_i2c if it is the board.SPI object because it is // We don't need to move original_i2c if it is the board.I2C object because it is
// statically allocated already. (Doing so would also make it impossible to reference in // statically allocated already. (Doing so would also make it impossible to reference in
// a subsequent VM run.) // a subsequent VM run.)
if (original_i2c == common_hal_board_get_i2c()) { if (original_i2c == common_hal_board_get_i2c()) {
@ -232,7 +134,7 @@ void reset_displays(void) {
} }
} }
} else { } else {
// Not an active display. // Not an active display bus.
continue; continue;
} }
} }
@ -240,9 +142,12 @@ void reset_displays(void) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
// Reset the displayed group. Only the first will get the terminal but // Reset the displayed group. Only the first will get the terminal but
// that's ok. // that's ok.
displayio_display_obj_t* display = &displays[i].display; if (displays[i].display.base.type == &displayio_display_type) {
display->auto_brightness = true; reset_display(&displays[i].display);
common_hal_displayio_display_show(display, NULL); } 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);
}
} }
} }
@ -254,8 +159,11 @@ void displayio_gc_collect(void) {
// Alternatively, we could use gc_collect_root over the whole object, // Alternatively, we could use gc_collect_root over the whole object,
// but this is more precise, and is the only field that needs marking. // but this is more precise, and is the only field that needs marking.
gc_collect_ptr(displays[i].display.current_group); if (displays[i].display.base.type == &displayio_display_type) {
displayio_display_collect_ptrs(&displays[i].display);
} else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) {
displayio_epaperdisplay_collect_ptrs(&displays[i].epaper_display);
}
} }
} }

View File

@ -28,6 +28,7 @@
#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H
#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/EPaperDisplay.h"
#include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Group.h"
#include "shared-bindings/displayio/I2CDisplay.h" #include "shared-bindings/displayio/I2CDisplay.h"
@ -39,14 +40,17 @@ typedef struct {
displayio_i2cdisplay_obj_t i2cdisplay_bus; displayio_i2cdisplay_obj_t i2cdisplay_bus;
displayio_parallelbus_obj_t parallel_bus; displayio_parallelbus_obj_t parallel_bus;
}; };
union {
displayio_display_obj_t display; displayio_display_obj_t display;
displayio_epaperdisplay_obj_t epaper_display;
};
} primary_display_t; } primary_display_t;
extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
extern displayio_group_t circuitpython_splash; extern displayio_group_t circuitpython_splash;
void displayio_refresh_displays(void); void displayio_background(void);
void reset_displays(void); void reset_displays(void);
void displayio_gc_collect(void); void displayio_gc_collect(void);

View File

@ -0,0 +1,325 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/displayio/Display.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/FourWire.h"
#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/ParallelBus.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
#include <stdint.h>
#include <string.h>
#include "tick.h"
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) {
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->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"));
}
self->bus = bus;
supervisor_start_terminal(width, height);
self->width = width;
self->height = height;
self->ram_width = ram_width;
self->ram_height = ram_height;
rotation = rotation % 360;
self->transform.x = 0;
self->transform.y = 0;
self->transform.scale = 1;
self->transform.mirror_x = false;
self->transform.mirror_y = false;
self->transform.transpose_xy = false;
if (rotation == 0 || rotation == 180) {
if (rotation == 180) {
self->transform.mirror_x = true;
self->transform.mirror_y = true;
}
} else {
self->transform.transpose_xy = true;
if (rotation == 270) {
self->transform.mirror_y = true;
} else {
self->transform.mirror_x = true;
}
}
self->area.x1 = 0;
self->area.y1 = 0;
self->area.next = NULL;
self->transform.dx = 1;
self->transform.dy = 1;
if (self->transform.transpose_xy) {
self->area.x2 = height;
self->area.y2 = width;
if (self->transform.mirror_x) {
self->transform.x = height;
self->transform.dx = -1;
}
if (self->transform.mirror_y) {
self->transform.y = width;
self->transform.dy = -1;
}
} else {
self->area.x2 = width;
self->area.y2 = height;
if (self->transform.mirror_x) {
self->transform.x = width;
self->transform.dx = -1;
}
if (self->transform.mirror_y) {
self->transform.y = height;
self->transform.dy = -1;
}
}
}
bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group) {
if (root_group == NULL) {
if (!circuitpython_splash.in_group) {
root_group = &circuitpython_splash;
} else if (self->current_group == &circuitpython_splash) {
return true;
}
}
if (root_group == self->current_group) {
return true;
}
if (root_group != NULL && root_group->in_group) {
return false;
}
if (self->current_group != NULL) {
self->current_group->in_group = false;
}
if (root_group != NULL) {
displayio_group_update_transform(root_group, &self->transform);
root_group->in_group = true;
}
self->current_group = root_group;
self->full_refresh = true;
return true;
}
uint16_t displayio_display_core_get_width(displayio_display_core_t* self){
return self->width;
}
uint16_t displayio_display_core_get_height(displayio_display_core_t* self){
return self->height;
}
bool displayio_display_core_bus_free(displayio_display_core_t *self) {
return self->bus_free(self->bus);
}
bool displayio_display_core_begin_transaction(displayio_display_core_t* self) {
return self->begin_transaction(self->bus);
}
void displayio_display_core_end_transaction(displayio_display_core_t* self) {
self->end_transaction(self->bus);
}
void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area) {
uint16_t x1 = area->x1;
uint16_t x2 = area->x2;
uint16_t y1 = area->y1;
uint16_t y2 = area->y2;
// Collapse down the dimension where multiple pixels are in a byte.
if (self->colorspace.depth < 8) {
uint8_t pixels_per_byte = 8 / self->colorspace.depth;
if (self->colorspace.pixels_in_byte_share_row) {
x1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
x2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
} else {
y1 /= pixels_per_byte * self->colorspace.bytes_per_cell;
y2 /= pixels_per_byte * self->colorspace.bytes_per_cell;
}
}
display_chip_select_behavior_t chip_select = CHIP_SELECT_UNTOUCHED;
if (always_toggle_chip_select || data_as_commands) {
chip_select = CHIP_SELECT_TOGGLE_EVERY_BYTE;
}
// Set column.
displayio_display_core_begin_transaction(self);
uint8_t data[5];
data[0] = column_command;
uint8_t data_length = 1;
display_byte_type_t data_type = DISPLAY_DATA;
if (!data_as_commands) {
self->send(self->bus, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, data, 1);
data_length = 0;
} else {
data_type = DISPLAY_COMMAND;
}
if (self->ram_width < 0x100) {
data[data_length++] = x1 + self->colstart;
data[data_length++] = x2 - 1 + self->colstart;
} else {
x1 += self->colstart;
x2 += self->colstart - 1;
data[data_length++] = x1 >> 8;
data[data_length++] = x1 & 0xff;
data[data_length++] = x2 >> 8;
data[data_length++] = x2 & 0xff;
}
self->send(self->bus, data_type, chip_select, data, data_length);
displayio_display_core_end_transaction(self);
if (set_current_column_command != NO_COMMAND) {
uint8_t command = set_current_column_command;
displayio_display_core_begin_transaction(self);
self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1);
self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2);
displayio_display_core_end_transaction(self);
}
// Set row.
displayio_display_core_begin_transaction(self);
data[0] = row_command;
data_length = 1;
if (!data_as_commands) {
self->send(self->bus, DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, data, 1);
data_length = 0;
}
if (self->ram_height < 0x100) {
data[data_length++] = y1 + self->rowstart;
data[data_length++] = y2 - 1 + self->rowstart;
} else {
y1 += self->rowstart;
y2 += self->rowstart - 1;
data[data_length++] = y1 >> 8;
data[data_length++] = y1 & 0xff;
data[data_length++] = y2 >> 8;
data[data_length++] = y2 & 0xff;
}
self->send(self->bus, data_type, chip_select, data, data_length);
displayio_display_core_end_transaction(self);
if (set_current_row_command != NO_COMMAND) {
uint8_t command = set_current_row_command;
displayio_display_core_begin_transaction(self);
self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1);
self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2);
displayio_display_core_end_transaction(self);
}
}
void displayio_display_core_start_refresh(displayio_display_core_t* self) {
self->last_refresh = ticks_ms;
}
void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
if (self->current_group != NULL) {
displayio_group_finish_refresh(self->current_group);
}
self->full_refresh = false;
self->last_refresh = ticks_ms;
}
void release_display_core(displayio_display_core_t* self) {
if (self->current_group != NULL) {
self->current_group->in_group = false;
}
}
void displayio_display_core_collect_ptrs(displayio_display_core_t* self) {
gc_collect_ptr(self->current_group);
}
bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) {
return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer);
}
bool displayio_display_core_clip_area(displayio_display_core_t *self, const displayio_area_t* area, displayio_area_t* clipped) {
bool overlaps = displayio_area_compute_overlap(&self->area, area, clipped);
if (!overlaps) {
return false;
}
// Expand the area if we have multiple pixels per byte and we need to byte
// align the bounds.
if (self->colorspace.depth < 8) {
uint8_t pixels_per_byte = 8 / self->colorspace.depth * self->colorspace.bytes_per_cell;
if (self->colorspace.pixels_in_byte_share_row) {
if (clipped->x1 % pixels_per_byte != 0) {
clipped->x1 -= clipped->x1 % pixels_per_byte;
}
if (clipped->x2 % pixels_per_byte != 0) {
clipped->x2 += pixels_per_byte - clipped->x2 % pixels_per_byte;
}
} else {
if (clipped->y1 % pixels_per_byte != 0) {
clipped->y1 -= clipped->y1 % pixels_per_byte;
}
if (clipped->y2 % pixels_per_byte != 0) {
clipped->y2 += pixels_per_byte - clipped->y2 % pixels_per_byte;
}
}
}
return true;
}

View File

@ -0,0 +1,85 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H
#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H
#include "shared-bindings/displayio/__init__.h"
#include "shared-bindings/displayio/Group.h"
#include "shared-module/displayio/area.h"
#define NO_COMMAND 0x100
typedef struct {
mp_obj_t bus;
displayio_group_t *current_group;
uint64_t last_refresh;
display_bus_bus_reset bus_reset;
display_bus_bus_free bus_free;
display_bus_begin_transaction begin_transaction;
display_bus_send send;
display_bus_end_transaction end_transaction;
displayio_buffer_transform_t transform;
displayio_area_t area;
uint16_t width;
uint16_t height;
uint16_t rotation;
uint16_t ram_width;
uint16_t ram_height;
_displayio_colorspace_t colorspace;
int16_t colstart;
int16_t rowstart;
bool full_refresh; // New group means we need to refresh the whole display.
} displayio_display_core_t;
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);
bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group);
uint16_t displayio_display_core_get_width(displayio_display_core_t* self);
uint16_t displayio_display_core_get_height(displayio_display_core_t* self);
bool displayio_display_core_bus_free(displayio_display_core_t *self);
bool displayio_display_core_begin_transaction(displayio_display_core_t* self);
void displayio_display_core_end_transaction(displayio_display_core_t* self);
void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area);
void release_display_core(displayio_display_core_t* self);
void displayio_display_core_start_refresh(displayio_display_core_t* self);
void displayio_display_core_finish_refresh(displayio_display_core_t* self);
void displayio_display_core_collect_ptrs(displayio_display_core_t* self);
bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer);
bool displayio_display_core_clip_area(displayio_display_core_t *self, const displayio_area_t* area, displayio_area_t* clipped);
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_CORE_H

View File

@ -151,37 +151,49 @@ _displayio_color_t blinka_colors[7] = {
.rgb888 = 0x000000, .rgb888 = 0x000000,
.rgb565 = 0x0000, .rgb565 = 0x0000,
.luma = 0x00, .luma = 0x00,
.chroma = 0,
.transparent = true .transparent = true
}, },
{ {
.rgb888 = 0x8428bc, .rgb888 = 0x8428bc,
.rgb565 = 0x7889, .rgb565 = 0x7889,
.luma = 0xff // We cheat the luma here. It is actually 0x60 .luma = 0xff, // We cheat the luma here. It is actually 0x60
.hue = 184,
.chroma = 148
}, },
{ {
.rgb888 = 0xff89bc, .rgb888 = 0xff89bc,
.rgb565 = 0xB8FC, .rgb565 = 0xB8FC,
.luma = 0xb5 .luma = 0xb5,
.hue = 222,
.chroma = 118
}, },
{ {
.rgb888 = 0x7beffe, .rgb888 = 0x7beffe,
.rgb565 = 0x9F86, .rgb565 = 0x9F86,
.luma = 0xe0 .luma = 0xe0,
.hue = 124,
.chroma = 131
}, },
{ {
.rgb888 = 0x51395f, .rgb888 = 0x51395f,
.rgb565 = 0x0D5A, .rgb565 = 0x0D5A,
.luma = 0x47 .luma = 0x47,
.hue = 185,
.chroma = 38
}, },
{ {
.rgb888 = 0xffffff, .rgb888 = 0xffffff,
.rgb565 = 0xffff, .rgb565 = 0xffff,
.luma = 0xff .luma = 0xff,
.chroma = 0
}, },
{ {
.rgb888 = 0x0736a0, .rgb888 = 0x0736a0,
.rgb565 = 0xf501, .rgb565 = 0xf501,
.luma = 0x44 .luma = 0x44,
.hue = 147,
.chroma = 153
}, },
}; };

View File

@ -102,12 +102,14 @@ _displayio_color_t terminal_colors[2] = {
{ {
.rgb888 = 0x000000, .rgb888 = 0x000000,
.rgb565 = 0x0000, .rgb565 = 0x0000,
.luma = 0x00 .luma = 0x00,
.chroma = 0
}, },
{ {
.rgb888 = 0xffffff, .rgb888 = 0xffffff,
.rgb565 = 0xffff, .rgb565 = 0xffff,
.luma = 0xff .luma = 0xff,
.chroma = 0
}, },
}; };