diff options
| author | Dan Halbert <halbert@halwitz.org> | 2019-06-13 21:55:07 -0400 |
|---|---|---|
| committer | Dan Halbert <halbert@halwitz.org> | 2019-06-13 21:55:07 -0400 |
| commit | bed6d43a768838fd3bc5d2048bf7acdc6e9b0a33 (patch) | |
| tree | 814683e585940b502d4e47f8556a69045729c77a | |
| parent | 6fed24e1b6fce58f2c06328b9bc8b8f9d9512b42 (diff) | |
| parent | 6be7cf7440acb827d4b0f767b6083a859499b045 (diff) | |
merge from upstream; WIP redo Address; no more AddressType
175 files changed, 3341 insertions, 1216 deletions
diff --git a/.gitignore b/.gitignore index 69f71847b..3e5bd2830 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ # Packages ############ +dist/ +*.egg-info # Logs and Databases ###################### @@ -25,6 +27,7 @@ ###################### build/ bin/ +circuitpython-stubs/ # Test failure outputs ###################### diff --git a/.travis.yml b/.travis.yml index 6d849e229..1702089c3 100755 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ git: # that SDK is shortest and add it there. In the case of major re-organizations, # just try to make the builds "about equal in run time" env: - - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express capablerobot_usbhub pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini electronut_labs_papyr" TRAVIS_SDK=arm:nrf + - TRAVIS_TESTS="unix docs translations website" TRAVIS_BOARDS="circuitplayground_express mini_sam_m4 grandcentral_m4_express capablerobot_usbhub pygamer pca10056 pca10059 feather_nrf52840_express makerdiary_nrf52840_mdk makerdiary_nrf52840_mdk_usb_dongle particle_boron particle_argon particle_xenon sparkfun_nrf52840_mini electronut_labs_papyr electronut_labs_blip" TRAVIS_SDK=arm:nrf - TRAVIS_BOARDS="metro_m0_express metro_m4_express metro_m4_airlift_lite pirkey_m0 trellis_m4_express trinket_m0 sparkfun_lumidrive sparkfun_redboard_turbo bast_pro_mini_m0" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_radiofruit_zigbee gemma_m0 hallowing_m0_express itsybitsy_m0_express itsybitsy_m4_express meowmeow sam32 uchip escornabot_makech" TRAVIS_SDK=arm - TRAVIS_BOARDS="feather_m0_express_crickit feather_m0_rfm69 feather_m0_rfm9x feather_m4_express arduino_zero arduino_mkr1300 arduino_mkrzero pewpew10 kicksat-sprite ugame10 robohatmm1" TRAVIS_SDK=arm @@ -1,4 +1,4 @@ -# Makefile for Sphinx documentation +# Top-level Makefile for documentation builds and miscellaneous tasks. # # You can set these variables from the command line. @@ -17,6 +17,13 @@ CONFDIR = . FORCE = -E VERBOSE = -v +# path to generated type stubs +STUBDIR = circuitpython-stubs +# Run "make VALIDATE= stubs" to avoid validating generated stub files +VALIDATE = -v +# path to pypi source distributions +DISTDIR = dist + # Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the # full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the # executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) @@ -31,7 +38,7 @@ I18NSPHINXOPTS = $(BASEOPTS) TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/nrf py shared-bindings shared-module supervisor -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext stubs help: @echo "Please use \`make <target>' where <target> is one of" @@ -60,6 +67,7 @@ help: clean: rm -rf $(BUILDDIR)/* + rm -rf $(STUBDIR) $(DISTDIR) *.egg-info html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @@ -203,3 +211,11 @@ translate: locale/circuitpython.pot check-translate: locale/circuitpython.pot $(wildcard locale/*.po) $(PYTHON) tools/check_translations.py $^ + +stubs: + rst2pyi $(VALIDATE) shared-bindings/ $(STUBDIR) + python setup.py sdist + +update-frozen-libraries: + @echo "Updating all frozen libraries to latest tagged version." + cd frozen; for library in *; do cd $$library; ../../tools/git-checkout-latest-tag.sh; cd ..; done diff --git a/README.rst b/README.rst index 53ac4cbcd..f5f9cccea 100644 --- a/README.rst +++ b/README.rst @@ -115,8 +115,8 @@ Behavior output is written to ``boot_out.txt``. - ``code.py`` (or ``main.py``) is run after every reload until it finishes or is interrupted. After it is done running, the vm and - hardware is reinitialized. **This means you cannot read state from - ``code.py`` in the REPL anymore.** CircuitPython's goal for this + hardware is reinitialized. **This means you cannot read state from** + ``code.py`` **in the REPL anymore.** CircuitPython's goal for this change includes reduce confusion about pins and memory being used. - After ``code.py`` the REPL can be entered by pressing any key. It no longer shares state with ``code.py`` so it is a fresh vm. @@ -131,9 +131,9 @@ Behavior ``samd.disable_autoreload()``) - Entering the REPL after the main code is finished requires a key press which enters the REPL and disables autoreload. -- Main is one of these: ``code.txt``, **``code.py``**, ``main.py``, +- Main is one of these: ``code.txt``, ``code.py``, ``main.py``, ``main.txt`` -- Boot is one of these: ``settings.txt``, ``settings.py``, **``boot.py``**, +- Boot is one of these: ``settings.txt``, ``settings.py``, ``boot.py``, ``boot.txt`` API diff --git a/locale/ID.po b/locale/ID.po index f5c0c0949..c1760e6b4 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -518,6 +518,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Channel EXTINT sedang digunakan" @@ -546,6 +547,10 @@ msgstr "" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -852,6 +857,10 @@ msgid "LHS of keyword arg must be an id" msgstr "LHS dari keyword arg harus menjadi sebuah id" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -932,6 +941,10 @@ msgstr "Tidak ada GCLK yang kosong" msgid "No hardware random available" msgstr "" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1015,6 +1028,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "Tambahkan module apapun pada filesystem\n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2176,7 +2193,7 @@ msgstr "" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 34070dc69..d32502e18 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:41-0700\n" +"POT-Creation-Date: 2019-06-12 00:59-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -506,6 +506,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "" @@ -534,6 +535,10 @@ msgstr "" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "" @@ -827,6 +832,10 @@ msgid "LHS of keyword arg must be an id" msgstr "" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -907,6 +916,10 @@ msgstr "" msgid "No hardware random available" msgstr "" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -989,6 +1002,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2131,7 +2148,7 @@ msgstr "" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 2cb97c3d3..2bdaaf712 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -510,6 +510,7 @@ msgid "Drive mode not used when direction is input." msgstr "Drive mode wird nicht verwendet, wenn die Richtung input ist." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "EXTINT Kanal ist schon in Benutzung" @@ -538,6 +539,10 @@ msgstr "Eine UUID wird erwartet" msgid "Expected tuple of length %d, got %d" msgstr "Habe ein Tupel der Länge %d erwartet aber %d erhalten" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "Akquirieren des Mutex gescheitert" @@ -833,6 +838,10 @@ msgid "LHS of keyword arg must be an id" msgstr "LHS des Schlüsselwortarguments muss eine id sein" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "Layer muss eine Group- oder TileGrid-Unterklasse sein." @@ -920,6 +929,10 @@ msgstr "Keine freien GCLKs" msgid "No hardware random available" msgstr "Kein hardware random verfügbar" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1004,6 +1017,10 @@ msgstr "Pixel außerhalb der Puffergrenzen" msgid "Plus any modules on the filesystem\n" msgstr "und alle Module im Dateisystem \n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2178,7 +2195,7 @@ msgstr "Objekt ist kein Iterator" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "Objekt ist nicht in sequence" diff --git a/locale/en_US.po b/locale/en_US.po index ebc18cfae..152ece432 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -506,6 +506,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "" @@ -534,6 +535,10 @@ msgstr "" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "" @@ -827,6 +832,10 @@ msgid "LHS of keyword arg must be an id" msgstr "" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -907,6 +916,10 @@ msgstr "" msgid "No hardware random available" msgstr "" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -989,6 +1002,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2131,7 +2148,7 @@ msgstr "" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index 04706abdc..d91dc95ca 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -510,6 +510,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Avast! EXTINT channel already in use" @@ -538,6 +539,10 @@ msgstr "" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "" @@ -831,6 +836,10 @@ msgid "LHS of keyword arg must be an id" msgstr "" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -911,6 +920,10 @@ msgstr "" msgid "No hardware random available" msgstr "" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -993,6 +1006,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2135,7 +2152,7 @@ msgstr "" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "" diff --git a/locale/es.po b/locale/es.po index 77739f49c..d954d574c 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -524,6 +524,7 @@ msgid "Drive mode not used when direction is input." msgstr "Modo Drive no se usa cuando la dirección es input." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "El canal EXTINT ya está siendo utilizado" @@ -554,6 +555,10 @@ msgstr "Se espera un %q" msgid "Expected tuple of length %d, got %d" msgstr "Se esperaba un tuple de %d, se obtuvo %d" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -862,6 +867,10 @@ msgid "LHS of keyword arg must be an id" msgstr "LHS del agumento por palabra clave deberia ser un identificador" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "Layer debe ser una subclase de Group o TileGrid." @@ -946,6 +955,10 @@ msgstr "Sin GCLKs libres" msgid "No hardware random available" msgstr "No hay hardware random disponible" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1035,6 +1048,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "Incapaz de montar de nuevo el sistema de archivos" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2213,7 +2230,7 @@ msgstr "objeto no es un iterator" msgid "object not callable" msgstr "objeto no puede ser llamado" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "objeto no en secuencia" diff --git a/locale/fil.po b/locale/fil.po index 5954e29b4..b6ad3643c 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy <me@timothygarcia.ca>\n" "Language-Team: fil\n" @@ -519,6 +519,7 @@ msgid "Drive mode not used when direction is input." msgstr "Drive mode ay hindi ginagamit kapag ang direksyon ay input." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Ginagamit na ang EXTINT channel" @@ -549,6 +550,10 @@ msgstr "Umasa ng %q" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -857,6 +862,10 @@ msgid "LHS of keyword arg must be an id" msgstr "LHS ng keyword arg ay dapat na id" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -941,6 +950,10 @@ msgstr "Walang libreng GCLKs" msgid "No hardware random available" msgstr "Walang magagamit na hardware random" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1028,6 +1041,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "Kasama ang kung ano pang modules na sa filesystem\n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2212,7 +2229,7 @@ msgstr "object ay hindi iterator" msgid "object not callable" msgstr "hindi matatawag ang object" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "object wala sa sequence" diff --git a/locale/fr.po b/locale/fr.po index 0bd0f8771..6fd6e9015 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n" "Language-Team: fr\n" @@ -522,6 +522,7 @@ msgid "Drive mode not used when direction is input." msgstr "Le mode Drive n'est pas utilisé quand la direction est 'input'." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Canal EXTINT déjà utilisé" @@ -552,6 +553,10 @@ msgstr "Un UUID est attendu" msgid "Expected tuple of length %d, got %d" msgstr "Tuple de longueur %d attendu, obtenu %d" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -865,6 +870,10 @@ msgid "LHS of keyword arg must be an id" msgstr "La partie gauche de l'argument nommé doit être un identifiant" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "'Layer' doit être un 'Group' ou une sous-classe 'TileGrid'." @@ -949,6 +958,10 @@ msgstr "Pas de GCLK libre" msgid "No hardware random available" msgstr "Pas de source matérielle d'aléa disponible" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1045,6 +1058,10 @@ msgstr "Pixel au-delà des limites du tampon" msgid "Plus any modules on the filesystem\n" msgstr "Ainsi que tout autre module présent sur le système de fichiers\n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger." @@ -2247,7 +2264,7 @@ msgstr "l'objet n'est pas un itérateur" msgid "object not callable" msgstr "objet non appelable" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "l'objet n'est pas dans la séquence" diff --git a/locale/it_IT.po b/locale/it_IT.po index 12f21c38e..d89d4ae07 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n" "Language-Team: \n" @@ -519,6 +519,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Canale EXTINT già in uso" @@ -549,6 +550,10 @@ msgstr "Atteso un %q" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -859,6 +864,10 @@ msgid "LHS of keyword arg must be an id" msgstr "" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "Layer deve essere un Group o TileGrid subclass" @@ -940,6 +949,10 @@ msgstr "Nessun GCLK libero" msgid "No hardware random available" msgstr "Nessun generatore hardware di numeri casuali disponibile" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1033,6 +1046,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "Imposssibile rimontare il filesystem" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2208,7 +2225,7 @@ msgstr "l'oggetto non è un iteratore" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "oggetto non in sequenza" diff --git a/locale/pl.po b/locale/pl.po index 1a7471f72..e7dc248be 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n" "Language-Team: pl\n" @@ -509,6 +509,7 @@ msgid "Drive mode not used when direction is input." msgstr "Tryb sterowania nieużywany w trybie wejścia." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Kanał EXTINT w użyciu" @@ -537,6 +538,10 @@ msgstr "Oczekiwano UUID" msgid "Expected tuple of length %d, got %d" msgstr "Oczekiwano krotkę długości %d, otrzymano %d" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "Nie udało się uzyskać blokady" @@ -832,6 +837,10 @@ msgid "LHS of keyword arg must be an id" msgstr "Lewa strona argumentu nazwanego musi być nazwą" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "Layer musi dziedziczyć z Group albo TileGrid" @@ -917,6 +926,10 @@ msgstr "Brak wolnych GLCK" msgid "No hardware random available" msgstr "Brak generatora liczb losowych" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -999,6 +1012,10 @@ msgstr "Piksel poza granicami bufora" msgid "Plus any modules on the filesystem\n" msgstr "Oraz moduły w systemie plików\n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Dowolny klawisz aby uruchomić konsolę. CTRL-D aby przeładować." @@ -2156,7 +2173,7 @@ msgstr "obiekt nie jest iteratorem" msgid "object not callable" msgstr "obiekt nie jest wywoływalny" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "obiektu nie ma sekwencji" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 390610041..f08619187 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -514,6 +514,7 @@ msgid "Drive mode not used when direction is input." msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "Canal EXTINT em uso" @@ -544,6 +545,10 @@ msgstr "Esperado um" msgid "Expected tuple of length %d, got %d" msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Falha ao enviar comando." + #: ports/nrf/common-hal/bleio/Device.c #, fuzzy msgid "Failed to acquire mutex" @@ -850,6 +855,10 @@ msgid "LHS of keyword arg must be an id" msgstr "" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "" @@ -930,6 +939,10 @@ msgstr "Não há GCLKs livre" msgid "No hardware random available" msgstr "" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "Sem suporte de hardware no pino de clock" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1016,6 +1029,10 @@ msgstr "" msgid "Plus any modules on the filesystem\n" msgstr "Não é possível remontar o sistema de arquivos" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "Buffer Ps2 vazio" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "" @@ -2165,7 +2182,7 @@ msgstr "" msgid "object not callable" msgstr "" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "objeto não em seqüência" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 82264cb52..dd61f1362 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-05-13 17:34-0700\n" +"POT-Creation-Date: 2019-06-11 14:59-0700\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -510,6 +510,7 @@ msgid "Drive mode not used when direction is input." msgstr "Fāngxiàng shūrù shí qūdòng móshì méiyǒu shǐyòng." #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "EXTINT channel already in use" msgstr "EXTINT píndào yǐjīng shǐyòng" @@ -538,6 +539,10 @@ msgstr "Yùqí UUID" msgid "Expected tuple of length %d, got %d" msgstr "Qīwàng de chángdù wèi %d de yuán zǔ, dédào %d" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "" + #: ports/nrf/common-hal/bleio/Device.c msgid "Failed to acquire mutex" msgstr "Wúfǎ huòdé mutex" @@ -833,6 +838,10 @@ msgid "LHS of keyword arg must be an id" msgstr "Guānjiàn zì arg de LHS bìxū shì id" #: shared-module/displayio/Group.c +msgid "Layer already in a group." +msgstr "" + +#: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass." msgstr "Layer bìxū shì Group huò TileGrid zi lèi." @@ -917,6 +926,10 @@ msgstr "Méiyǒu miǎnfèi de GCLKs" msgid "No hardware random available" msgstr "Méiyǒu kěyòng de yìngjiàn suíjī" +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +msgid "No hardware support on clk pin" +msgstr "" + #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "No hardware support on pin" @@ -1004,6 +1017,10 @@ msgstr "Xiàngsù chāochū huǎnchōng qū biānjiè" msgid "Plus any modules on the filesystem\n" msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n" +#: shared-bindings/ps2io/Ps2.c +msgid "Pop from an empty Ps2 buffer" +msgstr "" + #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload." msgstr "Àn xià rènhé jiàn jìnrù REPL. Shǐyòng CTRL-D chóngxīn jiāzài." @@ -2168,7 +2185,7 @@ msgstr "duìxiàng bùshì diédài qì" msgid "object not callable" msgstr "duìxiàng wúfǎ diàoyòng" -#: py/sequence.c +#: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" msgstr "duìxiàng bùshì xùliè" @@ -455,6 +455,11 @@ void gc_collect(void) { // This collects root pointers from the VFS mount table. Some of them may // have lost their references in the VM even though they are mounted. gc_collect_root((void**)&MP_STATE_VM(vfs_mount_table), sizeof(mp_vfs_mount_t) / sizeof(mp_uint_t)); + + #if CIRCUITPY_DISPLAYIO + displayio_gc_collect(); + #endif + // This naively collects all object references from an approximate stack // range. gc_collect_root((void**)sp, ((uint32_t)&_estack - sp) / sizeof(uint32_t)); diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 9b110c1bb..8e3fe9460 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -99,10 +99,9 @@ endif #Debugging/Optimization ifeq ($(DEBUG), 1) - # Turn on Python modules useful for debugging (e.g. uheap, ustack). CFLAGS += -ggdb # You may want to disable -flto if it interferes with debugging. - CFLAGS += -flto + CFLAGS += -flto -flto-partition=none # You may want to enable these flags to make setting breakpoints easier. # CFLAGS += -fno-inline -fno-ipa-sra ifeq ($(CHIP_FAMILY), samd21) @@ -112,13 +111,18 @@ else # -finline-limit can shrink the image size. # -finline-limit=80 or so is similar to not having it on. # There is no simple default value, though. - ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) - CFLAGS += -finline-limit=50 + + # Do a default shrink for small builds. + ifndef CFLAGS_INLINE_LIMIT + ifeq ($(CIRCUITPY_SMALL_BUILD),1) + CFLAGS_INLINE_LIMIT = 50 + endif endif + ifdef CFLAGS_INLINE_LIMIT CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT) endif - CFLAGS += -flto + CFLAGS += -flto -flto-partition=none endif CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk index bafb8a96c..a543468e5 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -4,9 +4,10 @@ USB_PID = 0x8053 USB_PRODUCT = "Arduino MKR1300" USB_MANUFACTURER = "Arduino" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 - -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk index b6df8d6e2..5612eb88d 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -1,12 +1,14 @@ LD_FILE = boards/samd21x18-bootloader.ld USB_VID = 0x239A -USB_PID = 0x8035 +USB_PID = 0x8050 USB_PRODUCT = "Arduino MKRZero" USB_MANUFACTURER = "Arduino" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk index af953e8c2..cbbf15a3e 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x824D USB_PRODUCT = "Arduino Zero" USB_MANUFACTURER = "Arduino" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk index 0e9bf7b45..08e42aa4e 100644 --- a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk @@ -4,9 +4,9 @@ USB_PID = 0xBAB3 USB_PRODUCT = "Bast Pro Mini M0" USB_MANUFACTURER = "Electronic Cats" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 - -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk index 88a059dcf..97c8eb863 100644 --- a/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk +++ b/ports/atmel-samd/boards/capablerobot_usbhub/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0xEDB3 USB_PRODUCT = "Programmable USB Hub" USB_MANUFACTURER = "Capable Robot Components" +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C @@ -13,6 +16,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51G19A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk index 9cdfca5b1..2399aad5c 100644 --- a/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk +++ b/ports/atmel-samd/boards/catwan_usbstick/mpconfigboard.mk @@ -4,9 +4,9 @@ USB_PID = 0xBAB2 USB_PRODUCT = "CatWAN USBStick" USB_MANUFACTURER = "Electronic Cats" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 - -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk index 652d20137..3c43776f5 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0x8019 USB_PRODUCT = "CircuitPlayground Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" @@ -14,8 +17,8 @@ CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 +CFLAGS_INLINE_LIMIT = 55 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice @@ -24,10 +27,3 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor - -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 35 -else -CFLAGS_INLINE_LIMIT = 55 -endif diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index bdcb4d350..f456515f9 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -4,26 +4,23 @@ USB_PID = 0x8019 USB_PRODUCT = "CircuitPlayground Express with Crickit libraries" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" -# Turn off longints for Crickit build to make room for additional frozen libs. -LONGINT_IMPL = NONE +# Turn off features and optimizations for Crickit build to make room for additional frozen libs. +LONGINT_IMPL = NONE CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_PIXELBUF = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 35 -else +SUPEROPT_GC = 0 CFLAGS_INLINE_LIMIT = 55 -endif + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk index 0444a37b9..72a191044 100644 --- a/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/cp32-m4/mpconfigboard.mk @@ -4,14 +4,15 @@ USB_PID = 0x8021 USB_PRODUCT = "CP32-M4" USB_MANUFACTURER = "Nadda-Reel Company LLC" +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q128JV_PM" -# No I2S on SAMD51G +CIRCUITPY_PS2IO = 1 +# No I2S on SAMD51G. CIRCUITPY_AUDIOBUSIO = 0 -# No touch on SAMD51 yet +# No touch on SAMD51 yet. CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J20A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index e6b21e25b..794920fe3 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -4,17 +4,16 @@ USB_PID = 0x0001 USB_PRODUCT = "Datalore IP M4" USB_MANUFACTURER = "TG-Boards" +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 3 EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JV_IQ, W25Q16JV_IM" - LONGINT_IMPL = MPZ -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk index 4d4649506..a2c182e68 100644 --- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0xBAB6 USB_PRODUCT = "Escornabot Makech" USB_MANUFACTURER = "Electronic Cats" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk index 26e3b7d4d..a88dbd563 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8015 USB_PRODUCT = "Feather M0 Adalogger" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk index 102cb656f..076f1f8ff 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8015 USB_PRODUCT = "Feather M0" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index a6190267d..756c293ad 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -4,15 +4,13 @@ USB_PID = 0x8023 USB_PRODUCT = "Feather M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" LONGINT_IMPL = MPZ -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) CFLAGS_INLINE_LIMIT = 60 -endif +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk index 620a0d505..5793d82e5 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0x8023 USB_PRODUCT = "Feather M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" @@ -14,13 +17,8 @@ CIRCUITPY_BITBANGIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 - -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - -CFLAGS_INLINE_LIMIT = 50 - CIRCUITPY_GAMEPAD = 0 +CFLAGS_INLINE_LIMIT = 50 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk index ce3f8668c..83d794d04 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8015 USB_PRODUCT = "Feather M0 RFM69" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk index 282977338..a84e14f55 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8015 USB_PRODUCT = "Feather M0 RFM9x" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 4bae6ffa7..33229044b 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -4,10 +4,10 @@ USB_PID = 0x8023 USB_PRODUCT = "Feather M0 Supersized" USB_MANUFACTURER = "Dave Astels" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ - -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 4fddcffc1..8169345f5 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -4,17 +4,16 @@ USB_PID = 0x8026 USB_PRODUCT = "Feather M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" -QSPI_FLASH_FILESYSTEM = 1 +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk index d9350ea22..c4a3a5a19 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0x8023 USB_PRODUCT = "Feather RadioFruit Zigbee" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMR21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" @@ -13,6 +16,3 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 # No DAC on SAMR21G CIRCUITPY_AUDIOIO = 0 - -CHIP_VARIANT = SAMR21G18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk index 9f4a9fe83..6f44a22f8 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x801D USB_PRODUCT = "Gemma M0" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk index 63158681b..13631a736 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.mk @@ -4,14 +4,14 @@ USB_PID = 0x8032 USB_PRODUCT = "Grand Central M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" -QSPI_FLASH_FILESYSTEM = 1 +CHIP_VARIANT = SAMD51P20A +CHIP_FAMILY = samd51 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ +CIRCUITPY_PS2IO = 1 # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51P20A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 1df82ff44..8dfc741e5 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0xD1ED USB_PRODUCT = "HalloWing M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" @@ -13,11 +16,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_AUDIOBUSIO = 0 - -CFLAGS_INLINE_LIMIT = 50 - -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index 4f3e1ca66..e427e9430 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -4,17 +4,13 @@ USB_PID = 0x8012 USB_PRODUCT = "ItsyBitsy M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q16FW, GD25Q16C" LONGINT_IMPL = MPZ -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 45 -else -CFLAGS_INLINE_LIMIT = 70 -endif +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index d4d674d9d..31bb38e20 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -4,15 +4,16 @@ USB_PID = 0x802C USB_PRODUCT = "ItsyBitsy M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ +CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51G19A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index e97a70105..5871cca2a 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -4,14 +4,15 @@ USB_PID = 0xED94 USB_PRODUCT = "kicksat-sprite" USB_MANUFACTURER = "maholli" +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 0 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 +# Not needed. CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_DISPLAYIO = 0 - -CHIP_VARIANT = SAMD51G19A -CHIP_FAMILY = samd51
\ No newline at end of file diff --git a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk index 3f9601d32..894e19a6b 100644 --- a/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk +++ b/ports/atmel-samd/boards/meowmeow/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0xBAB1 USB_PRODUCT = "Meow Meow" USB_MANUFACTURER = "Electronic Cats" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index ce9c4baba..93a8ffc11 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -4,16 +4,13 @@ USB_PID = 0x8014 USB_PRODUCT = "Metro M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C" - LONGINT_IMPL = MPZ -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 50 -endif +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk index 654a84eb8..d7d0c1d6e 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -4,17 +4,16 @@ USB_PID = 0x8038 USB_PRODUCT = "Metro M4 Airlift Lite" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 3 EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" - LONGINT_IMPL = MPZ -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 35162b678..829bf749f 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -4,17 +4,16 @@ USB_PID = 0x8021 USB_PRODUCT = "Metro M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 3 EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C" - LONGINT_IMPL = MPZ -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - CIRCUITPY_NETWORK = 1 MICROPY_PY_WIZNET5K = 5500 +CIRCUITPY_PS2IO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk index 27bad2693..a8f47dced 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -4,16 +4,16 @@ USB_PID = 0x2017 USB_PRODUCT = "Mini SAM M4" USB_MANUFACTURER = "Benjamin Shockley" +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q16JV_IM" - LONGINT_IMPL = MPZ +CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51G19A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk index b36a21368..e24a29051 100644 --- a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk @@ -4,13 +4,12 @@ USB_PID = 0x801D USB_PRODUCT = "PewPew 10.2" USB_MANUFACTURER = "Radomir Dopieralski" -INTERNAL_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = NONE - CHIP_VARIANT = SAMD21E18A CHIP_FAMILY = samd21 -FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_SMALL_BUILD = 1 CIRCUITPY_PEW = 1 CIRCUITPY_ANALOGIO = 1 @@ -20,9 +19,7 @@ CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_SAMD = 0 CIRCUITPY_USB_MIDI = 0 -CIRCUITPY_SMALL_BUILD = 1 -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 40 -endif +SUPEROPT_GC = 0 + +FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk index 4405b7a35..686c9099f 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk @@ -4,6 +4,9 @@ USB_PID = 0x8028 USB_PRODUCT = "pIRKey M0" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE @@ -19,11 +22,8 @@ CIRCUITPY_SAMD = 0 CIRCUITPY_USB_MIDI = 1 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_SMALL_BUILD = 1 - -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 - -CFLAGS_INLINE_LIMIT = 25 +# Make more room. +SUPEROPT_GC = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 2b0e334fa..64fb8e852 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -87,8 +87,8 @@ void board_init(void) { display->base.type = &displayio_display_type; common_hal_displayio_display_construct(display, bus, - 160, // Width - 128, // Height + 160, // Width (after rotation) + 128, // Height (after rotation) 0, // column start 0, // row start 270, // rotation diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk index aba0e333d..b8d10387b 100644 --- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -1,25 +1,23 @@ LD_FILE = boards/samd51x19-bootloader-external-flash.ld USB_VID = 0x239A -USB_PID = 0x802C +USB_PID = 0x8034 USB_PRODUCT = "PyBadge" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD51J19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 - -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - CIRCUITPY_STAGE = 1 -CIRCUITPY_GAMEPAD = 1 -CIRCUITPY_DISPLAYIO = 1 -CIRCUITPY_AUDIOIO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk index 8523e31be..a1ff90747 100644 --- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -1,25 +1,23 @@ LD_FILE = boards/samd51x19-bootloader-external-flash.ld USB_VID = 0x239A -USB_PID = 0x802E +USB_PID = 0x803E USB_PRODUCT = "PyGamer" 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 -# No touch on SAMD51 yet -CIRCUITPY_TOUCHIO = 0 - +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_GAMEPAD = 1 CIRCUITPY_GAMEPADSHIFT = 1 - -CHIP_VARIANT = SAMD51J19A -CHIP_FAMILY = samd51 - CIRCUITPY_STAGE = 1 -CIRCUITPY_GAMEPAD = 1 -CIRCUITPY_DISPLAYIO = 1 -CIRCUITPY_AUDIOIO = 1 +# No touch on SAMD51 yet +CIRCUITPY_TOUCHIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer/pins.c b/ports/atmel-samd/boards/pygamer/pins.c index aa0c3e39b..9d0d196e7 100644 --- a/ports/atmel-samd/boards/pygamer/pins.c +++ b/ports/atmel-samd/boards/pygamer/pins.c @@ -43,6 +43,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) }, { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) }, + // SDCS, dup of D4 + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA14) }, + // Special named pins { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA15) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_PB04) }, diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk index 34a94ac2b..996b17b3b 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.mk @@ -1,17 +1,16 @@ LD_FILE = boards/samd51x20-bootloader-external-flash.ld USB_VID = 0x239A -USB_PID = 0x8032 +USB_PID = 0x8036 USB_PRODUCT = "PyPortal" USB_MANUFACTURER = "Adafruit Industries LLC" -QSPI_FLASH_FILESYSTEM = 1 +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 +QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J20A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk index da7da2761..9523984b7 100644 --- a/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk +++ b/ports/atmel-samd/boards/robohatmm1/mpconfigboard.mk @@ -4,23 +4,25 @@ USB_PID = 0x4D43 USB_PRODUCT = "Robo HAT MM1" USB_MANUFACTURER = "Robotics Masters" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + # Non-Flash Edition #INTERNAL_FLASH_FILESYSTEM = 1 #LONGINT_IMPL = NONE +#SUPEROPT_GC = 0 # SPI-Flash Edition SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ" LONGINT_IMPL = MPZ - -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 - # Make room for frozen Libraries CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FREQUENCYIO = 0 +CFLAGS_INLINE_LIMIT = 55 + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_INA219 @@ -29,6 +31,3 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw - -#Adding per @danh to reduce memory usage and get the latest changes in -CFLAGS_INLINE_LIMIT = 55 diff --git a/ports/atmel-samd/boards/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk index d76696b39..ca1e11f01 100644 --- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk @@ -4,11 +4,11 @@ USB_PID = 0xEDBE USB_PRODUCT = "SAM32" USB_MANUFACTURER = "maholli" +CHIP_VARIANT = SAMD51J20A +CHIP_FAMILY = samd51 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51J20A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk index 4da42c02d..9d0ef1c04 100755 --- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk @@ -4,16 +4,15 @@ USB_PID = 0x0017 USB_PRODUCT = "LUMIDrive Board" USB_MANUFACTURER = "SparkFun Electronics" -SPI_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 -CIRCUITPY_AUDIOIO = 0 -CIRCUITPY_AUDIOBUSIO = 0 - +SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q32FV" +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_AUDIOBUSIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index 9e45f8ad9..3be1a17d3 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -4,16 +4,13 @@ USB_PID = 0x0015 USB_PRODUCT = "RedBoard Turbo Board" USB_MANUFACTURER = "SparkFun Electronics" -SPI_FLASH_FILESYSTEM = 1 -LONGINT_IMPL = MPZ - CHIP_VARIANT = SAMD21G18A CHIP_FAMILY = samd21 +SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = "W25Q32FV" +LONGINT_IMPL = MPZ -# Tweak inlining depending on language. -ifeq ($(TRANSLATION), zh_Latn_pinyin) -CFLAGS_INLINE_LIMIT = 50 -endif +CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk index c0238ce80..c9d0baf11 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8D23 USB_PRODUCT = "SparkFun SAMD21 Dev Breakout" USB_MANUFACTURER = "SparkFun" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk index 462e3e2ca..a6e216575 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x8D22 USB_PRODUCT = "SparkFun SAMD21 Mini Breakout" USB_MANUFACTURER = "SparkFun" +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21G18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk index 93b07bc76..6d108e649 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trellis_m4_express/mpconfigboard.mk @@ -4,15 +4,16 @@ USB_PID = 0x8030 USB_PRODUCT = "Trellis M4 Express" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD51G19A +CHIP_FAMILY = samd51 + QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 2 EXTERNAL_FLASH_DEVICES = "W25Q64JV_IQ, GD25Q64C" LONGINT_IMPL = MPZ +CIRCUITPY_PS2IO = 1 # No I2S on SAMD51G CIRCUITPY_AUDIOBUSIO = 0 # No touch on SAMD51 yet CIRCUITPY_TOUCHIO = 0 - -CHIP_VARIANT = SAMD51G19A -CHIP_FAMILY = samd51 diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk index 1c6f6db05..b4a00b654 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk @@ -4,9 +4,11 @@ USB_PID = 0x801F USB_PRODUCT = "Trinket M0" USB_MANUFACTURER = "Adafruit Industries LLC" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 +SUPEROPT_GC = 0 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk index c9c196da7..b9d36a741 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -4,10 +4,10 @@ USB_PID = 0x801F USB_PRODUCT="Trinket M0 Haxpress" USB_MANUFACTURER="Radomir Dopieralski" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = W25Q32BV LONGINT_IMPL = MPZ - -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.mk b/ports/atmel-samd/boards/uchip/mpconfigboard.mk index b6710af6d..109492b76 100644 --- a/ports/atmel-samd/boards/uchip/mpconfigboard.mk +++ b/ports/atmel-samd/boards/uchip/mpconfigboard.mk @@ -4,9 +4,9 @@ USB_PID = 0xED5F USB_PRODUCT = "uChip CircuitPython" USB_MANUFACTURER = "Itaca Innovation" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_SMALL_BUILD = 1 - -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index cafd84b21..a27ca8874 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -4,14 +4,14 @@ USB_PID = 0x801F USB_PRODUCT = "uGame10" USB_MANUFACTURER = "Radomir Dopieralski" +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICE_COUNT = 1 EXTERNAL_FLASH_DEVICES = S25FL216K LONGINT_IMPL = MPZ -CHIP_VARIANT = SAMD21E18A -CHIP_FAMILY = samd21 - CIRCUITPY_STAGE = 1 CIRCUITPY_MATH = 1 CIRCUITPY_AUDIOIO = 1 diff --git a/ports/atmel-samd/common-hal/ps2io/Ps2.c b/ports/atmel-samd/common-hal/ps2io/Ps2.c new file mode 100644 index 000000000..6a06864f2 --- /dev/null +++ b/ports/atmel-samd/common-hal/ps2io/Ps2.c @@ -0,0 +1,441 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> + * + * 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 "common-hal/ps2io/Ps2.h" + +#include <stdint.h> + +#include "atmel_start_pins.h" +#include "hal/include/hal_gpio.h" + +#include "background.h" +#include "eic_handler.h" +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "samd/external_interrupts.h" +#include "samd/pins.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/ps2io/Ps2.h" +#include "supervisor/shared/translate.h" + +#include "tick.h" + +#define STATE_IDLE 0 +#define STATE_RECV 1 +#define STATE_RECV_PARITY 2 +#define STATE_RECV_STOP 3 +#define STATE_RECV_ERR 10 + +#define ERROR_STARTBIT 0x01 +#define ERROR_TIMEOUT 0x02 +#define ERROR_PARITY 0x04 +#define ERROR_STOPBIT 0x08 +#define ERROR_BUFFER 0x10 + +#define ERROR_TX_CLKLO 0x100 +#define ERROR_TX_CLKHI 0x200 +#define ERROR_TX_ACKDATA 0x400 +#define ERROR_TX_ACKCLK 0x800 +#define ERROR_TX_RTS 0x1000 +#define ERROR_TX_NORESP 0x2000 + +static void ps2_set_config(ps2io_ps2_obj_t* self) { + uint32_t sense_setting = EIC_CONFIG_SENSE0_FALL_Val; + set_eic_handler(self->channel, EIC_HANDLER_PS2); + turn_on_eic_channel(self->channel, sense_setting); +} + +static void disable_interrupt(ps2io_ps2_obj_t* self) { + uint32_t mask = 1 << self->channel; + EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos; +} + +static void resume_interrupt(ps2io_ps2_obj_t* self) { + disable_interrupt(self); + + self->state = STATE_IDLE; + gpio_set_pin_function(self->clk_pin, GPIO_PIN_FUNCTION_A); + uint32_t mask = 1 << self->channel; + EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos; + EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos; + + ps2_set_config(self); +} + +static void clk_hi(ps2io_ps2_obj_t* self) { + // External pull-up + // Must set pull after setting direction. + gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF); +} + +static bool wait_clk_lo(ps2io_ps2_obj_t* self, uint32_t us) { + clk_hi(self); + common_hal_mcu_delay_us(1); + while (gpio_get_pin_level(self->clk_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static bool wait_clk_hi(ps2io_ps2_obj_t* self, uint32_t us) { + clk_hi(self); + common_hal_mcu_delay_us(1); + while (!gpio_get_pin_level(self->clk_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static void clk_lo(ps2io_ps2_obj_t* self) { + gpio_set_pin_pull_mode(self->clk_pin, GPIO_PULL_OFF); + gpio_set_pin_direction(self->clk_pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->clk_pin, 0); +} + +static void data_hi(ps2io_ps2_obj_t* self) { + // External pull-up + gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF); +} + +static bool wait_data_lo(ps2io_ps2_obj_t* self, uint32_t us) { + data_hi(self); + common_hal_mcu_delay_us(1); + while (gpio_get_pin_level(self->data_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static bool wait_data_hi(ps2io_ps2_obj_t* self, uint32_t us) { + data_hi(self); + common_hal_mcu_delay_us(1); + while (!gpio_get_pin_level(self->data_pin) && us) { + --us; + common_hal_mcu_delay_us(1); + } + return us; +} + +static void data_lo(ps2io_ps2_obj_t* self) { + gpio_set_pin_pull_mode(self->data_pin, GPIO_PULL_OFF); + gpio_set_pin_direction(self->data_pin, GPIO_DIRECTION_OUT); + gpio_set_pin_level(self->data_pin, 0); +} + +static void idle(ps2io_ps2_obj_t* self) { + clk_hi(self); + data_hi(self); +} + +static void inhibit(ps2io_ps2_obj_t* self) { + clk_lo(self); + data_hi(self); +} + +static void delay_us(uint32_t t) { + common_hal_mcu_delay_us(t); +} + +void ps2_interrupt_handler(uint8_t channel) { + // Grab the current time first. + uint32_t current_us; + uint64_t current_ms; + current_tick(¤t_ms, ¤t_us); + + ps2io_ps2_obj_t* self = get_eic_channel_data(channel); + int data_bit = gpio_get_pin_level(self->data_pin) ? 1 : 0; + + // test for timeout + if (self->state != STATE_IDLE) { + int64_t diff_ms = current_ms - self->last_int_ms; + if (diff_ms >= 2) { // a.k.a. > 1.001ms + self->last_errors |= ERROR_TIMEOUT; + self->state = STATE_IDLE; + } + } + + self->last_int_us = current_us; + self->last_int_ms = current_ms; + + if (self->state == STATE_IDLE) { + self->bits = 0; + self->parity = false; + self->bitcount = 0; + self->state = STATE_RECV; + if (data_bit) { + // start bit should be 0 + self->last_errors |= ERROR_STARTBIT; + self->state = STATE_RECV_ERR; + } else { + self->state = STATE_RECV; + } + + } else if (self->state == STATE_RECV) { + if (data_bit) { + self->bits |= data_bit << self->bitcount; + self->parity = !self->parity; + } + ++self->bitcount; + if (self->bitcount >= 8) { + self->state = STATE_RECV_PARITY; + } + + } else if (self->state == STATE_RECV_PARITY) { + ++self->bitcount; + if (data_bit) { + self->parity = !self->parity; + } + if (!self->parity) { + self->last_errors |= ERROR_PARITY; + self->state = STATE_RECV_ERR; + } else { + self->state = STATE_RECV_STOP; + } + + } else if (self->state == STATE_RECV_STOP) { + ++self->bitcount; + if (! data_bit) { + self->last_errors |= ERROR_STOPBIT; + } else if (self->waiting_cmd_response) { + self->cmd_response = self->bits; + self->waiting_cmd_response = false; + } else if (self->bufcount >= sizeof(self->buffer)) { + self->last_errors |= ERROR_BUFFER; + } else { + self->buffer[self->bufposw] = self->bits; + self->bufposw = (self->bufposw + 1) % sizeof(self->buffer); + self->bufcount++; + } + self->state = STATE_IDLE; + + } else if (self->state == STATE_RECV_ERR) { + // just count the bits until idle + if (++self->bitcount >= 10) { + self->state = STATE_IDLE; + } + } +} + +void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self, + const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin) { + if (!clk_pin->has_extint) { + mp_raise_RuntimeError(translate("No hardware support on clk pin")); + } + if (eic_get_enable() && !eic_channel_free(clk_pin->extint_channel)) { + mp_raise_RuntimeError(translate("EXTINT channel already in use")); + } + + clk_hi(self); + data_hi(self); + + self->channel = clk_pin->extint_channel; + self->clk_pin = clk_pin->number; + self->data_pin = data_pin->number; + self->state = STATE_IDLE; + self->bufcount = 0; + self->bufposr = 0; + self->bufposw = 0; + self->waiting_cmd_response = false; + + set_eic_channel_data(clk_pin->extint_channel, (void*) self); + + // Check to see if the EIC is enabled and start it up if its not.' + if (eic_get_enable() == 0) { + turn_on_external_interrupt_controller(); + } + + gpio_set_pin_function(clk_pin->number, GPIO_PIN_FUNCTION_A); + gpio_set_pin_function(data_pin->number, GPIO_PIN_FUNCTION_A); + + turn_on_cpu_interrupt(self->channel); + + claim_pin(clk_pin); + claim_pin(data_pin); + + // Set config will enable the EIC. + ps2_set_config(self); +} + +bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self) { + return self->clk_pin == NO_PIN; +} + +void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self) { + if (common_hal_ps2io_ps2_deinited(self)) { + return; + } + set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT); + turn_off_eic_channel(self->channel); + reset_pin_number(self->clk_pin); + reset_pin_number(self->data_pin); + self->clk_pin = NO_PIN; + self->data_pin = NO_PIN; +} + +uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self) { + return self->bufcount; +} + +bool common_hal_ps2io_ps2_get_paused(ps2io_ps2_obj_t* self) { + uint32_t mask = 1 << self->channel; + return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0; +} + +int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self) +{ + common_hal_mcu_disable_interrupts(); + if (self->bufcount <= 0) { + common_hal_mcu_enable_interrupts(); + return -1; + } + uint8_t b = self->buffer[self->bufposr]; + self->bufposr = (self->bufposr + 1) % sizeof(self->buffer); + self->bufcount -= 1; + common_hal_mcu_enable_interrupts(); + return b; +} + +uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self) +{ + common_hal_mcu_disable_interrupts(); + uint16_t errors = self->last_errors; + self->last_errors = 0; + common_hal_mcu_enable_interrupts(); + return errors; +} + +// Based upon TMK implementation of PS/2 protocol +// https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/protocol/ps2_interrupt.c + +int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b) +{ + disable_interrupt(self); + inhibit(self); + delay_us(100); + + /* RTS and start bit */ + data_lo(self); + clk_hi(self); + if (!wait_clk_lo(self, 10000)) { + self->last_errors |= ERROR_TX_RTS; + goto ERROR; + } + + bool parity = true; + for (uint8_t i = 0; i < 8; i++) { + delay_us(15); + if (b & (1 << i)) { + parity = !parity; + data_hi(self); + } else { + data_lo(self); + } + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_CLKHI; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_CLKLO; + goto ERROR; + } + } + + delay_us(15); + if (parity) { + data_hi(self); + } else { + data_lo(self); + } + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_CLKHI; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_CLKLO; + goto ERROR; + } + + /* Stop bit */ + delay_us(15); + data_hi(self); + + /* Ack */ + if (!wait_data_lo(self, 50)) { + self->last_errors |= ERROR_TX_ACKDATA; + goto ERROR; + } + if (!wait_clk_lo(self, 50)) { + self->last_errors |= ERROR_TX_ACKCLK; + goto ERROR; + } + + /* wait for idle state */ + if (!wait_clk_hi(self, 50)) { + self->last_errors |= ERROR_TX_ACKCLK; + goto ERROR; + } + if (!wait_data_hi(self, 50)) { + self->last_errors |= ERROR_TX_ACKDATA; + goto ERROR; + } + + /* Wait for response byte */ + self->waiting_cmd_response = true; + idle(self); + resume_interrupt(self); + + for (int i = 0; i < 25; ++i) { + delay_us(1000); + common_hal_mcu_disable_interrupts(); + bool has_response = !self->waiting_cmd_response; + uint8_t response = self->cmd_response; + common_hal_mcu_enable_interrupts(); + + if (has_response) { + return response; + } + } + + /* No response */ + common_hal_mcu_disable_interrupts(); + self->waiting_cmd_response = false; + self->last_errors |= ERROR_TX_NORESP; + common_hal_mcu_enable_interrupts(); + return -1; + + /* Other errors */ +ERROR: + idle(self); + resume_interrupt(self); + return -1; +} diff --git a/shared-bindings/bleio/AddressType.h b/ports/atmel-samd/common-hal/ps2io/Ps2.h index e69caffab..cce6ae474 100644 --- a/shared-bindings/bleio/AddressType.h +++ b/ports/atmel-samd/common-hal/ps2io/Ps2.h @@ -1,9 +1,10 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,27 +25,38 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H -#include "py/obj.h" - -typedef enum { - ADDRESS_PUBLIC, - ADDRESS_RANDOM_STATIC, - ADDRESS_RANDOM_PRIVATE_RESOLVABLE, - ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE -} bleio_address_type_t; +#include "common-hal/microcontroller/Pin.h" -extern const mp_obj_type_t bleio_addresstype_type; +#include "py/obj.h" typedef struct { mp_obj_base_t base; -} bleio_addresstype_obj_t; + uint8_t channel; + uint8_t clk_pin; + uint8_t data_pin; + + uint8_t state; + uint64_t last_int_ms; + uint32_t last_int_us; + + uint16_t bits; + bool parity; + uint8_t bitcount; + + uint8_t buffer[16]; + uint8_t bufcount; + uint8_t bufposr; + uint8_t bufposw; + + uint16_t last_errors; + + bool waiting_cmd_response; + uint8_t cmd_response; +} ps2io_ps2_obj_t; -extern const bleio_addresstype_obj_t bleio_addresstype_public_obj; -extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj; -extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj; -extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj; +void ps2_interrupt_handler(uint8_t channel); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PS2IO_PS2_H diff --git a/ports/atmel-samd/common-hal/ps2io/__init__.c b/ports/atmel-samd/common-hal/ps2io/__init__.c new file mode 100644 index 000000000..ba4b4249f --- /dev/null +++ b/ports/atmel-samd/common-hal/ps2io/__init__.c @@ -0,0 +1 @@ +// No ps2io module functions. diff --git a/ports/atmel-samd/eic_handler.c b/ports/atmel-samd/eic_handler.c index db5f260e5..30ecaa7ca 100644 --- a/ports/atmel-samd/eic_handler.c +++ b/ports/atmel-samd/eic_handler.c @@ -25,6 +25,7 @@ */ #include "common-hal/pulseio/PulseIn.h" +#include "common-hal/ps2io/Ps2.h" #include "common-hal/rotaryio/IncrementalEncoder.h" #include "shared-bindings/microcontroller/__init__.h" //#include "samd/external_interrupts.h" @@ -46,6 +47,12 @@ void shared_eic_handler(uint8_t channel) { break; #endif +#if CIRCUITPY_PS2IO + case EIC_HANDLER_PS2: + ps2_interrupt_handler(channel); + break; +#endif + #if CIRCUITPY_ROTARYIO case EIC_HANDLER_INCREMENTAL_ENCODER: incrementalencoder_interrupt_handler(channel); diff --git a/ports/atmel-samd/eic_handler.h b/ports/atmel-samd/eic_handler.h index 2f9ccd67f..71b0fce67 100644 --- a/ports/atmel-samd/eic_handler.h +++ b/ports/atmel-samd/eic_handler.h @@ -29,6 +29,7 @@ #define EIC_HANDLER_NO_INTERRUPT 0x0 #define EIC_HANDLER_PULSEIN 0x1 #define EIC_HANDLER_INCREMENTAL_ENCODER 0x2 +#define EIC_HANDLER_PS2 0x3 void set_eic_handler(uint8_t channel, uint8_t eic_handler); void shared_eic_handler(uint8_t channel); diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 4f53d30f9..37360deb0 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -52,6 +52,7 @@ #include "common-hal/pulseio/PulseIn.h" #include "common-hal/pulseio/PulseOut.h" #include "common-hal/pulseio/PWMOut.h" +#include "common-hal/ps2io/Ps2.h" #include "common-hal/rtc/RTC.h" #include "common-hal/touchio/TouchIn.h" #include "samd/cache.h" diff --git a/ports/atmel-samd/tools/gen_pin_name_table.py b/ports/atmel-samd/tools/gen_pin_name_table.py index 76c9cf255..ded64e5f6 100644 --- a/ports/atmel-samd/tools/gen_pin_name_table.py +++ b/ports/atmel-samd/tools/gen_pin_name_table.py @@ -156,6 +156,9 @@ capabilities = { "PA14", "PA15", "PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23", "PA30", "PA31"] }, + "ps2io": { + "Ps2": ALL_BUT_USB, + }, "touchio": { "TouchIn": ["PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06", "PA07", "PB02", "PB03"] diff --git a/ports/nrf/README.md b/ports/nrf/README.md index 65a66b7b0..5f6d03720 100644 --- a/ports/nrf/README.md +++ b/ports/nrf/README.md @@ -79,6 +79,7 @@ feather_nrf52840_express | s140 | Peripheral and Scanner | UF makerdiary_nrf52840_mdk | s140 | Peripheral and Scanner | pyocd or ARM mbed DAPLink makerdiary_nrf52840_mdk_usb_dongle | s140 | Peripheral and Scanner | DFU bootloader & nrfutil electronut_labs_papyr | s140 | Peripheral and Scanner | UF2 bootloader +electronut_labs_blip | s140 | Peripheral and Scanner | Black Magic Probe ## Segger Targets diff --git a/ports/nrf/background.c b/ports/nrf/background.c index 3fb5febd3..9c4f3ab27 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -29,7 +29,7 @@ #include "supervisor/usb.h" #include "supervisor/shared/stack.h" -#ifdef CIRCUITPY_DISPLAYIO +#if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" #endif @@ -48,7 +48,7 @@ void run_background_tasks(void) { filesystem_background(); usb_background(); - #ifdef CIRCUITPY_DISPLAYIO + #if CIRCUITPY_DISPLAYIO displayio_refresh_displays(); #endif running_background_tasks = false; diff --git a/ports/nrf/boards/electronut_labs_blip/README.md b/ports/nrf/boards/electronut_labs_blip/README.md new file mode 100644 index 000000000..c34ef16f8 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/README.md @@ -0,0 +1,67 @@ +# Setup + +The `Electronut Labs Blip` board is a development board based on the `nRF52840` SoC from +Nordic Semiconductors. It has a Black Magic Probe compatible programmer and debugger +built in, along with temperature/humidity sensor, ambient light intensity sensor, and +a 3-axis accelerometer. It can be used to prototype very low power devices. It also has +provision for an SD card slot, which makes it a complete and versatile development board. + +Schematic, datasheet, pin mapping etc. can be found over [here](https://docs.electronut.in/blip/). + +Features: + +* Raytac MDBT50Q-1M module based on Nordic Semiconductor's nRF52840 +* LIS2DDH12 High-performance 3-axis "femto" accelerometer +* Optical Sensor LTR-329ALS-01 +* Si7006-A20 I2C humidity and temperature sensor +* On board STM32F103CBT6 as Black magic probe debugger +* NFC Antenna +* MicroSD slot +* Power Supply: USB, JST connector for Li-ion/Li-po +* BQ24079 battery charging and power management IC + +## Installing CircuitPython submodules + +Before you can build, you will need to run the following commands once, which +will install the submodules that are part of the CircuitPython ecosystem, and +build the `mpy-cross` tool: + +``` +$ cd circuitpython +$ git submodule update --init +$ make -C mpy-cross +``` + +## Building and Flashing CircuitPython + +No special notes for this, follow `ports/nrf` generic `README.md`. + +### Flashing CircuitPython with GDB using on board Black magic probe debugger + +``` +$ cd ports/nrf +$ make V=1 SD=s140 SERIAL=/dev/ttyACM0 BOARD=electronut_labs_blip all +... +... +LINK build-electronut_labs_blip-s140/firmware.elf + +778588 bytes free in flash out of 1048576 bytes ( 1024.0 kb ). +228320 bytes free in ram for stack out of 245760 bytes ( 240.0 kb ). + +Create build-electronut_labs_blip-s140/firmware.bin +Create build-electronut_labs_blip-s140/firmware.hex +Create build-electronut_labs_blip-s140/firmware.uf2 +python3 ../../tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "build-electronut_labs_blip-s140/firmware.uf2" build-electronut_labs_blip-s140/firmware.hex +Converting to uf2, output size: 540160, start address: 0x26000 +Wrote 540160 bytes to build-electronut_labs_blip-s140/firmware.uf2. +``` + +Now you can use either `.hex` or `.elf` from the generated files inside +`build-electronut_labs_blip-s140` directory. Now you can use `arm-none-eabi-gdb` +to flash circuitpython on Blip. + +### Other tips + +Once circuitpython is running on your board, it will come up as a mass storage +device named `CIRCUITPY`, where you can drop in your python code. The file names +it looks for are `main.py`, `main.txt`, `code.py` or `code.txt`. diff --git a/ports/nrf/boards/electronut_labs_blip/board.c b/ports/nrf/boards/electronut_labs_blip/board.c new file mode 100644 index 000000000..4421970ee --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 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" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h new file mode 100644 index 000000000..21e8c3ef6 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * Copyright (c) 2019 tavish@electronut.in + * + * 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 "nrfx/hal/nrf_gpio.h" + +#define ELECTRONUT_LABS_PAPYR + +#define MICROPY_HW_BOARD_NAME "Electronut Labs Blip" +#define MICROPY_HW_MCU_NAME "nRF52840" +#define MICROPY_PY_SYS_PLATFORM "ElectronutLabsPapyr" + +#define CIRCUITPY_AUTORELOAD_DELAY_MS 500 + +// TODO #define CIRCUITPY_INTERNAL_NVM_SIZE 8192 + +#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_12) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_25) +#define DEFAULT_SPI_BUS_MOSI (&pin_P1_02) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_24) + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) +#define DEFAULT_UART_BUS_TX (&pin_P0_06) diff --git a/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk new file mode 100644 index 000000000..bf82400d1 --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/mpconfigboard.mk @@ -0,0 +1,22 @@ +USB_VID = 0x239A +USB_PID = 0x803C +USB_PRODUCT = "Blip" +USB_MANUFACTURER = "Electronut Labs" + +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +MCU_CHIP = nrf52840 +SD ?= s140 +SOFTDEV_VERSION ?= 6.1.0 + +BOOT_SETTING_ADDR = 0xFF000 + +ifeq ($(SD),) + LD_FILE = boards/nrf52840_1M_256k.ld +else + LD_FILE = boards/adafruit_$(MCU_SUB_VARIANT)_$(SD_LOWER)_v$(firstword $(subst ., ,$(SOFTDEV_VERSION))).ld + CIRCUITPY_BLEIO = 1 +endif + +NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
\ No newline at end of file diff --git a/ports/nrf/boards/electronut_labs_blip/pins.c b/ports/nrf/boards/electronut_labs_blip/pins.c new file mode 100644 index 000000000..a8f9af1cd --- /dev/null +++ b/ports/nrf/boards/electronut_labs_blip/pins.c @@ -0,0 +1,72 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + // odd row + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_P1_06) }, + + // even row + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_P1_08) }, + + // SCL SDA as pins also + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_17) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P0_14) }, + + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_P0_13) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P0_18) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 540659aa1..120fcf055 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -136,17 +136,15 @@ void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { uint32_t err_code; common_hal_bleio_adapter_set_enabled(true); - -#if (BLE_API_VERSION == 2) - err_code = sd_ble_gap_address_get(&local_address); -#else err_code = sd_ble_gap_addr_get(&local_address); -#endif if (err_code != NRF_SUCCESS) { mp_raise_OSError_msg(translate("Failed to get local address")); } address->type = local_address.addr_type; - memcpy(address->value, local_address.addr, BLEIO_ADDRESS_BYTES); + + mp_buffer_info_t buf_info; + mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); + memcpy(address->bytes, buf_info.buf, NUM_BLEIO_ADDRESS_BYTES); } diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c index e522b50d2..e59676fde 100644 --- a/ports/nrf/common-hal/bleio/Peripheral.c +++ b/ports/nrf/common-hal/bleio/Peripheral.c @@ -32,6 +32,7 @@ #include "ble_drv.h" #include "ble_hci.h" #include "nrf_soc.h" +#include "py/gc.h" #include "py/objstr.h" #include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c index b76caaf21..08600bc0a 100644 --- a/ports/nrf/common-hal/bleio/Scanner.c +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -51,15 +51,14 @@ STATIC void on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) { return; } - // TODO: Don't add new entry for each item, group by address and update bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); entry->base.type = &bleio_scanentry_type; entry->rssi = report->rssi; + memcpy(entry->address.bytes, report->data.p_data, NUM_BLEIO_ADDRESS_BYTES); entry->address.type = report->peer_addr.addr_type; - memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); - entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data); + entry->data = mp_obj_new_bytes(report->data.p_data, report->data.len); mp_obj_list_append(scanner->adv_reports, entry); diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 85ecd6afe..8fbf75498 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -93,16 +93,22 @@ void reset_port(void) { i2c_reset(); spi_reset(); uart_reset(); + +#if CIRCUITPY_PULSEIO pwmout_reset(); pulseout_reset(); pulsein_reset(); +#endif + timers_reset(); - #if CIRCUITPY_RTC +#if CIRCUITPY_RTC rtc_reset(); - #endif +#endif +#if CIRCUITPY_BLEIO bleio_reset(); +#endif reset_all_pins(); } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 31af38d8d..fd43a11a6 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -162,6 +162,9 @@ endif ifeq ($(CIRCUITPY_PULSEIO),1) SRC_PATTERNS += pulseio/% endif +ifeq ($(CIRCUITPY_PS2IO),1) +SRC_PATTERNS += ps2io/% +endif ifeq ($(CIRCUITPY_RANDOM),1) SRC_PATTERNS += random/% endif @@ -251,6 +254,8 @@ $(filter $(SRC_PATTERNS), \ pulseio/PulseIn.c \ pulseio/PulseOut.c \ pulseio/__init__.c \ + ps2io/Ps2.c \ + ps2io/__init__.c \ rotaryio/IncrementalEncoder.c \ rotaryio/__init__.c \ rtc/RTC.c \ @@ -283,7 +288,6 @@ SRC_BINDINGS_ENUMS += \ SRC_BINDINGS_ENUMS += \ $(filter $(SRC_PATTERNS), \ bleio/Address.c \ - bleio/AddressType.c \ bleio/ScanEntry.c \ ) @@ -359,3 +363,8 @@ $(addprefix lib/,\ libm/atan2f.c \ ) endif + +.PHONY: check-release-needs-clean-build + +check-release-needs-clean-build: + @echo "RELEASE_NEEDS_CLEAN_BUILD = $(RELEASE_NEEDS_CLEAN_BUILD)" diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index f957886f4..2026185ef 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -72,6 +72,7 @@ #define MICROPY_KBD_EXCEPTION (1) #define MICROPY_MEM_STATS (0) #define MICROPY_NONSTANDARD_TYPECODES (0) +#define MICROPY_OPT_COMPUTED_GOTO (1) #define MICROPY_PERSISTENT_CODE_LOAD (1) #define MICROPY_PY_ARRAY (1) @@ -89,6 +90,7 @@ #define MICROPY_PY_BUILTINS_MIN_MAX (1) #define MICROPY_PY_BUILTINS_PROPERTY (1) #define MICROPY_PY_BUILTINS_REVERSED (1) +#define MICROPY_PY_BUILTINS_ROUND_INT (1) #define MICROPY_PY_BUILTINS_SET (1) #define MICROPY_PY_BUILTINS_SLICE (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) @@ -415,6 +417,13 @@ extern const struct _mp_obj_module_t pulseio_module; #define PULSEIO_MODULE #endif +#if CIRCUITPY_PS2IO +extern const struct _mp_obj_module_t ps2io_module; +#define PS2IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_ps2io), (mp_obj_t)&ps2io_module }, +#else +#define PS2IO_MODULE +#endif + #if CIRCUITPY_RANDOM extern const struct _mp_obj_module_t random_module; #define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, @@ -579,6 +588,7 @@ extern const struct _mp_obj_module_t ustack_module; PEW_MODULE \ PIXELBUF_MODULE \ PULSEIO_MODULE \ + PS2IO_MODULE \ RANDOM_MODULE \ RE_MODULE \ ROTARYIO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index b436929e0..47303a73a 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -32,13 +32,13 @@ # CIRCUITPY_FULL_BUILD = 0 ifndef CIRCUITPY_FULL_BUILD -ifeq ($(CIRCUITPY_SMALL_BUILD),1) -CIRCUITPY_FULL_BUILD = 0 -CFLAGS += -DCIRCUITPY_FULL_BUILD=0 -else -CIRCUITPY_FULL_BUILD = 1 -CFLAGS += -DCIRCUITPY_FULL_BUILD=1 -endif + ifeq ($(CIRCUITPY_SMALL_BUILD),1) + CIRCUITPY_FULL_BUILD = 0 + CFLAGS += -DCIRCUITPY_FULL_BUILD=0 + else + CIRCUITPY_FULL_BUILD = 1 + CFLAGS += -DCIRCUITPY_FULL_BUILD=1 + endif endif # All builtin modules are listed below, with default values (0 for off, 1 for on) @@ -153,6 +153,12 @@ CIRCUITPY_PULSEIO = 1 endif CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO) +# Only for SAMD boards for the moment +ifndef CIRCUITPY_PS2IO +CIRCUITPY_PS2IO = 0 +endif +CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO) + ifndef CIRCUITPY_RANDOM CIRCUITPY_RANDOM = 1 endif @@ -383,6 +383,10 @@ void gc_collect_start(void) { #endif } +void gc_collect_ptr(void *ptr) { + gc_mark(ptr); +} + void gc_collect_root(void **ptrs, size_t len) { for (size_t i = 0; i < len; i++) { void *ptr = ptrs[i]; @@ -43,6 +43,7 @@ bool gc_is_locked(void); // A given port must implement gc_collect by using the other collect functions. void gc_collect(void); void gc_collect_start(void); +void gc_collect_ptr(void *ptr); void gc_collect_root(void **ptrs, size_t len); void gc_collect_end(void); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 124dcd05a..e764f1987 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -455,13 +455,13 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) { return o_in; } - #if !MICROPY_PY_BUILTINS_ROUND_INT - mp_raise_NotImplementedError(NULL); - #else mp_int_t num_dig = mp_obj_get_int(args[1]); if (num_dig >= 0) { return o_in; } + #if !MICROPY_PY_BUILTINS_ROUND_INT + mp_raise_NotImplementedError(NULL); + #else mp_obj_t mult = mp_binary_op(MP_BINARY_OP_POWER, MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_SMALL_INT(-num_dig)); mp_obj_t half_mult = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, mult, MP_OBJ_NEW_SMALL_INT(2)); @@ -107,9 +107,9 @@ endif # External modules written in C. ifneq ($(USER_C_MODULES),) -# pre-define USERMOD variables as expanded so that variables are immediate +# pre-define USERMOD variables as expanded so that variables are immediate # expanded as they're added to them -SRC_USERMOD := +SRC_USERMOD := CFLAGS_USERMOD := LDFLAGS_USERMOD := $(foreach module, $(wildcard $(USER_C_MODULES)/*/micropython.mk), \ @@ -343,10 +343,23 @@ $(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h $(PY_BUILD)/nlr%.o: CFLAGS += -Os # optimising gc for speed; 5ms down to 4ms on pybv2 +ifndef SUPEROPT_GC + SUPEROPT_GC = 1 +endif + +ifeq ($(SUPEROPT_GC),1) $(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT) +endif # optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster) +ifndef SUPEROPT_VM + SUPEROPT_VM = 1 +endif + +ifeq ($(SUPEROPT_VM),1) $(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT) +endif + # Optimizing vm.o for modern deeply pipelined CPUs with branch predictors # may require disabling tail jump optimization. This will make sure that # each opcode has its own dispatching jump which will improve branch diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 615f4e2ce..a0e2d4065 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Winitializer-overrides" #endif // __clang__ @@ -113,6 +113,6 @@ static const void *const entry_table[256] = { [MP_BC_BINARY_OP_MULTI ... MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_NUM_BYTECODE - 1] = &&entry_MP_BC_BINARY_OP_MULTI, }; -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic pop #endif // __clang__ diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 000000000..7cd491ade --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +rst2pyi>=0.3.0 diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..1e0d81da3 --- /dev/null +++ b/setup.py @@ -0,0 +1,22 @@ +from datetime import datetime +from setuptools import setup +from pathlib import Path + +stub_root = Path("circuitpython-stubs") +stubs = [p.relative_to(stub_root).as_posix() for p in stub_root.glob("*.pyi")] + +now = datetime.utcnow() +version = now.strftime("%Y.%m.%d") + +setup( + name="circuitpython-stubs", + description="PEP 561 type stubs for CircuitPython", + url="https://github.com/adafruit/circuitpython", + maintainer="CircuitPythonistas", + author_email="circuitpython@adafruit.com", + version=version, + license="MIT", + package_data={"circuitpython-stubs": stubs}, + packages=["circuitpython-stubs"], + setup_requires=["setuptools>=38.6.0"], +) diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c index d7ae0116d..3ff208761 100644 --- a/shared-bindings/_pew/PewPew.c +++ b/shared-bindings/_pew/PewPew.c @@ -96,8 +96,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, mp_raise_TypeError(translate("Row entry must be digitalio.DigitalInOut")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(rows[i]); - raise_error_if_deinited( - common_hal_digitalio_digitalinout_deinited(pin)); + if (common_hal_digitalio_digitalinout_deinited(pin)) { + raise_deinited_error(); + } } for (size_t i = 0; i < cols_size; ++i) { @@ -105,8 +106,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, mp_raise_TypeError(translate("Column entry must be digitalio.DigitalInOut")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(cols[i]); - raise_error_if_deinited( - common_hal_digitalio_digitalinout_deinited(pin)); + if (common_hal_digitalio_digitalinout_deinited(pin)) { + raise_deinited_error(); + } } if (!MP_OBJ_IS_TYPE(args[ARG_buttons].u_obj, @@ -115,8 +117,9 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, } digitalio_digitalinout_obj_t *buttons = MP_OBJ_TO_PTR( args[ARG_buttons].u_obj); - raise_error_if_deinited( - common_hal_digitalio_digitalinout_deinited(buttons)); + if (common_hal_digitalio_digitalinout_deinited(buttons)) { + raise_deinited_error(); + } pew_obj_t *pew = MP_STATE_VM(pew_singleton); if (!pew) { diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index 7c2766aa3..420720e62 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -51,7 +51,7 @@ extern const int32_t colorwheel(float pos); //| //| :class:`~_pixelbuf.PixelBuf` implements an RGB[W] bytearray abstraction. //| -//| .. class:: PixelBuf(size, buf, byteorder=BGR, bpp=3) +//| .. class:: PixelBuf(size, buf, byteorder=BGR, brightness=0, rawbuf=None, offset=0, dotstar=False, auto_write=False, write_function=None, write_args=None) //| //| Create a PixelBuf object of the specified size, byteorder, and bits per pixel. //| @@ -66,14 +66,14 @@ extern const int32_t colorwheel(float pos); //| //| :param ~int size: Number of pixelsx //| :param ~bytearray buf: Bytearray to store pixel data in -//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` (also sets the bpp) +//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` //| :param ~float brightness: Brightness (0 to 1.0, default 1.0) //| :param ~bytearray rawbuf: Bytearray to store raw pixel colors in //| :param ~int offset: Offset from start of buffer (default 0) //| :param ~bool dotstar: Dotstar mode (default False) //| :param ~bool auto_write: Whether to automatically write pixels (Default False) //| :param ~callable write_function: (optional) Callable to use to send pixels -//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The +//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The //| PixelBuf instance is appended after these args. //| STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -95,7 +95,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a 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); - if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type)) + if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type)) mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj)); pixelbuf_byteorder_obj_t *byteorder = (args[ARG_byteorder].u_obj == mp_const_none) ? MP_OBJ_FROM_PTR(&byteorder_BGR) : args[ARG_byteorder].u_obj; @@ -122,7 +122,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a if (!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_list) && !MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_tuple) && - args[ARG_write_args].u_obj != mp_const_none) + args[ARG_write_args].u_obj != mp_const_none) { mp_raise_ValueError(translate("write_args must be a list, tuple, or None")); } @@ -186,8 +186,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a else if (self->brightness > 1) self->brightness = 1; } - - if (self->dotstar_mode) { + + if (self->dotstar_mode) { // Initialize the buffer with the dotstar start bytes. // Header and end must be setup by caller for (uint i = 0; i < self->pixels * 4; i += 4) { @@ -197,7 +197,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a } } } - + return MP_OBJ_FROM_PTR(self); } @@ -227,7 +227,7 @@ const mp_obj_property_t pixelbuf_pixelbuf_bpp_obj = { //| setting this value causes a recomputation of the values in buf. //| If only a buf was provided, then the brightness only applies to //| future pixel changes. -//| In DotStar mode +//| In DotStar mode //| STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) { mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); @@ -266,7 +266,7 @@ void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self) { // Compensate for shifted buffer (bpp=3 dotstar) for (uint i = 0; i < self->bytes; i++) { // Don't adjust per-pixel luminance bytes in dotstar mode - if (!self->dotstar_mode || (i % 4 != 0)) + if (!self->dotstar_mode || (i % 4 != 0)) buf[i] = rawbuf[i] * self->brightness; } } @@ -367,11 +367,13 @@ void call_write_function(pixelbuf_pixelbuf_obj_t *self) { } } - - -//| .. method:: [] +//| .. method:: __getitem__(index) +//| +//| Returns the pixel value at the given index. //| -//| Get or set pixels. Supports individual pixels and slices. +//| .. method:: __setitem__(index, value) +//| +//| Sets the pixel value at the given index. //| STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type)); @@ -380,7 +382,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp // delete item // slice deletion return MP_OBJ_NULL; // op not supported - } + } pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in); if (0) { @@ -390,7 +392,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp if (!mp_seq_get_fast_slice_indexes(self->bytes, index_in, &slice)) mp_raise_NotImplementedError(translate("Only slices with step=1 (aka None) are supported")); - if ((slice.stop * self->pixel_step) > self->bytes) + if ((slice.stop * self->pixel_step) > self->bytes) mp_raise_IndexError(translate("Range out of bounds")); if (value == MP_OBJ_SENTINEL) { // Get @@ -422,8 +424,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp for (size_t i = slice.start; i < slice.stop; i++) { mp_obj_t *item = src_objs[i-slice.start]; if (MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple) || MP_OBJ_IS_INT(value)) { - pixelbuf_set_pixel(self->buf + (i * self->pixel_step), - self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL, + pixelbuf_set_pixel(self->buf + (i * self->pixel_step), + self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL, self->brightness, item, &self->byteorder, self->dotstar_mode); } } @@ -438,14 +440,14 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp } else { // Single index rather than slice. size_t index = mp_get_index(self->base.type, self->pixels, index_in, false); size_t offset = (index * self->pixel_step); - if (offset > self->bytes) + if (offset > self->bytes) mp_raise_IndexError(translate("Pixel beyond bounds of buffer")); if (value == MP_OBJ_SENTINEL) { // Get uint8_t *pixelstart = (uint8_t *)(self->two_buffers ? self->rawbuf : self->buf) + offset; return pixelbuf_get_pixel(pixelstart, &self->byteorder, self->dotstar_mode); } else { // Store - pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, + pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, self->brightness, value, &self->byteorder, self->dotstar_mode); if (self->auto_write) call_write_function(self); diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c index 31defc7fb..48b9f1cef 100644 --- a/shared-bindings/_pixelbuf/__init__.c +++ b/shared-bindings/_pixelbuf/__init__.c @@ -53,7 +53,7 @@ //| //| PixelBuf -//| .. class:: ByteOrder +//| .. class:: ByteOrder() //| //| Classes representing byteorders for circuitpython @@ -169,34 +169,34 @@ const int32_t colorwheel(float pos) { /// RGB -//| .. class:: RGB +//| .. data:: RGB //| //| * **order** Red, Green, Blue //| * **bpp** 3 PIXELBUF_BYTEORDER(RGB, 3, 0, 1, 2, 3, false, false) -//| .. class:: RBG +//| .. data:: RBG //| //| * **order** Red, Blue, Green //| * **bpp** 3 PIXELBUF_BYTEORDER(RBG, 3, 0, 2, 1, 3, false, false) -//| .. class:: GRB +//| .. data:: GRB //| //| * **order** Green, Red, Blue //| * **bpp** 3 //| //| Commonly used by NeoPixel. PIXELBUF_BYTEORDER(GRB, 3, 1, 0, 2, 3, false, false) -//| .. class:: GBR +//| .. data:: GBR //| //| * **order** Green, Blue, Red //| * **bpp** 3 PIXELBUF_BYTEORDER(GBR, 3, 1, 2, 0, 3, false, false) -//| .. class:: BRG +//| .. data:: BRG //| //| * **order** Blue, Red, Green //| * **bpp** 3 PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false) -//| .. class:: BGR +//| .. data:: BGR //| //| * **order** Blue, Green, Red //| * **bpp** 3 @@ -205,19 +205,19 @@ PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false) PIXELBUF_BYTEORDER(BGR, 3, 2, 1, 0, 3, false, false) // RGBW -//| .. class:: RGBW +//| .. data:: RGBW //| //| * **order** Red, Green, Blue, White //| * **bpp** 4 //| * **has_white** True PIXELBUF_BYTEORDER(RGBW, 4, 0, 1, 2, 3, true, false) -//| .. class:: RBGW +//| .. data:: RBGW //| //| * **order** Red, Blue, Green, White //| * **bpp** 4 //| * **has_white** True PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false) -//| .. class:: GRBW +//| .. data:: GRBW //| //| * **order** Green, Red, Blue, White //| * **bpp** 4 @@ -225,19 +225,19 @@ PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false) //| //| Commonly used by RGBW NeoPixels. PIXELBUF_BYTEORDER(GRBW, 4, 1, 0, 2, 3, true, false) -//| .. class:: GBRW +//| .. data:: GBRW //| //| * **order** Green, Blue, Red, White //| * **bpp** 4 //| * **has_white** True PIXELBUF_BYTEORDER(GBRW, 4, 1, 2, 0, 3, true, false) -//| .. class:: BRGW +//| .. data:: BRGW //| //| * **order** Blue, Red, Green, White //| * **bpp** 4 //| * **has_white** True PIXELBUF_BYTEORDER(BRGW, 4, 2, 0, 1, 3, true, false) -//| .. class:: BGRW +//| .. data:: BGRW //| //| * **order** Blue, Green, Red, White //| * **bpp** 4 @@ -248,37 +248,37 @@ PIXELBUF_BYTEORDER(BGRW, 4, 2, 1, 0, 3, true, false) // Luminosity chosen because the luminosity of a Dotstar at full bright // burns the eyes like looking at the Sun. // https://www.thesaurus.com/browse/luminosity?s=t -//| .. class:: LRGB +//| .. data:: LRGB //| //| * **order** *Luminosity*, Red, Green, Blue //| * **bpp** 4 //| * **has_luminosity** True PIXELBUF_BYTEORDER(LRGB, 4, 1, 2, 3, 0, false, true) -//| .. class:: LRBG +//| .. data:: LRBG //| //| * **order** *Luminosity*, Red, Blue, Green //| * **bpp** 4 //| * **has_luminosity** True PIXELBUF_BYTEORDER(LRBG, 4, 1, 3, 2, 0, false, true) -//| .. class:: LGRB +//| .. data:: LGRB //| //| * **order** *Luminosity*, Green, Red, Blue //| * **bpp** 4 //| * **has_luminosity** True PIXELBUF_BYTEORDER(LGRB, 4, 2, 1, 3, 0, false, true) -//| .. class:: LGBR +//| .. data:: LGBR //| //| * **order** *Luminosity*, Green, Blue, Red //| * **bpp** 4 //| * **has_luminosity** True PIXELBUF_BYTEORDER(LGBR, 4, 2, 3, 1, 0, false, true) -//| .. class:: LBRG +//| .. data:: LBRG //| //| * **order** *Luminosity*, Blue, Red, Green //| * **bpp** 4 //| * **has_luminosity** True PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true) -//| .. class:: LBGR +//| .. data:: LBGR //| //| * **order** *Luminosity*, Blue, Green, Red //| * **bpp** 4 diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 116f82a03..a8bbbf59a 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -86,6 +86,11 @@ STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit); +STATIC void check_for_deinit(analogio_analogin_obj_t *self) { + if (common_hal_analogio_analogin_deinited(self)) { + raise_deinited_error(); + } +} //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -113,7 +118,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, //| STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_analogio_analogin_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self)); } MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value); @@ -132,7 +137,7 @@ const mp_obj_property_t analogio_analogin_value_obj = { //| STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_analogio_analogin_deinited(self)); + check_for_deinit(self); return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self)); } MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj, diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index dcbd7ecfb..0816da465 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -112,7 +112,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4 //| resolution, the value is 16-bit. STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_analogio_analogout_deinited(self)); + if (common_hal_analogio_analogout_deinited(self)) { + raise_deinited_error(); + } uint32_t v = mp_obj_get_int(value); if (v >= (1 << 16)) { mp_raise_ValueError(translate("AnalogOut is only 16 bits. Value must be less than 65536.")); diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 48424d073..980f11392 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -134,6 +134,11 @@ STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_deinit_obj, audiobusio_i2sout_deinit); +STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) { + if (common_hal_audiobusio_i2sout_deinited(self)) { + raise_deinited_error(); + } +} //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -169,7 +174,7 @@ STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_ar { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); 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); @@ -186,7 +191,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_ //| STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); common_hal_audiobusio_i2sout_stop(self); return mp_const_none; } @@ -198,7 +203,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop //| STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_playing(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_playing_obj, audiobusio_i2sout_obj_get_playing); @@ -216,7 +221,7 @@ const mp_obj_property_t audiobusio_i2sout_playing_obj = { //| STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); if (!common_hal_audiobusio_i2sout_get_playing(self)) { mp_raise_RuntimeError(translate("Not playing")); @@ -232,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pau //| STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); if (common_hal_audiobusio_i2sout_get_paused(self)) { common_hal_audiobusio_i2sout_resume(self); @@ -248,7 +253,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_re //| STATIC mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_paused(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_paused_obj, audiobusio_i2sout_obj_get_paused); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 5dca3fa59..0c92c2478 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -43,7 +43,7 @@ //| //| PDMIn can be used to record an input audio signal on a given set of pins. //| -//| .. class:: PDMIn(clock_pin, data_pin, \*, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11) +//| .. class:: PDMIn(clock_pin, data_pin, *, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11) //| //| Create a PDMIn object associated with the given pins. This allows you to //| record audio signals from the given pins. Individual ports may put further @@ -156,6 +156,11 @@ STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_deinit_obj, audiobusio_pdmin_deinit); +STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) { + if (common_hal_audiobusio_pdmin_deinited(self)) { + raise_deinited_error(); + } +} //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -188,7 +193,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, //| STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); - raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self)); + check_for_deinit(self); if (!MP_OBJ_IS_SMALL_INT(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) { mp_raise_TypeError(translate("destination_length must be an int >= 0")); } @@ -223,7 +228,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_reco //| STATIC mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audiobusio_pdmin_get_sample_rate(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_get_sample_rate_obj, audiobusio_pdmin_obj_get_sample_rate); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 9cb98d1f8..571dcdaca 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -133,6 +133,11 @@ STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_deinit_obj, audioio_audioout_deinit); +STATIC void check_for_deinit(audioio_audioout_obj_t *self) { + if (common_hal_audioio_audioout_deinited(self)) { + raise_deinited_error(); + } +} //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -170,7 +175,7 @@ STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_arg { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); 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); @@ -187,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl //| STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); common_hal_audioio_audioout_stop(self); return mp_const_none; } @@ -199,7 +204,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); //| STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_audioio_audioout_get_playing(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_playing_obj, audioio_audioout_obj_get_playing); @@ -217,7 +222,7 @@ const mp_obj_property_t audioio_audioout_playing_obj = { //| STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); if (!common_hal_audioio_audioout_get_playing(self)) { mp_raise_RuntimeError(translate("Not playing")); @@ -233,7 +238,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause //| STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); if (common_hal_audioio_audioout_get_paused(self)) { common_hal_audioio_audioout_resume(self); @@ -249,7 +254,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resu //| STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_audioout_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_audioio_audioout_get_paused(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_paused_obj, audioio_audioout_obj_get_paused); diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audioio/Mixer.c index 43ef2c524..dce4b3955 100644 --- a/shared-bindings/audioio/Mixer.c +++ b/shared-bindings/audioio/Mixer.c @@ -121,6 +121,12 @@ STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit); +STATIC void check_for_deinit(audioio_mixer_obj_t *self) { + if (common_hal_audioio_mixer_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -157,7 +163,7 @@ STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + check_for_deinit(self); 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); @@ -178,7 +184,7 @@ STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_ { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, }; audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + check_for_deinit(self); 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); @@ -193,7 +199,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_st //| STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) { audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing); @@ -211,7 +217,7 @@ const mp_obj_property_t audioio_mixer_playing_obj = { //| STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) { audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_mixer_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate); diff --git a/shared-bindings/audioio/RawSample.c b/shared-bindings/audioio/RawSample.c index 7fc896449..62998f580 100644 --- a/shared-bindings/audioio/RawSample.c +++ b/shared-bindings/audioio/RawSample.c @@ -115,6 +115,12 @@ STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_deinit_obj, audioio_rawsample_deinit); +STATIC void check_for_deinit(audioio_rawsample_obj_t *self) { + if (common_hal_audioio_rawsample_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -142,14 +148,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4, //| STATIC mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_rawsample_get_sample_rate(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_get_sample_rate_obj, audioio_rawsample_obj_get_sample_rate); STATIC mp_obj_t audioio_rawsample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self)); + check_for_deinit(self); common_hal_audioio_rawsample_set_sample_rate(self, mp_obj_get_int(sample_rate)); return mp_const_none; } diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audioio/WaveFile.c index cddeef769..242c915d3 100644 --- a/shared-bindings/audioio/WaveFile.c +++ b/shared-bindings/audioio/WaveFile.c @@ -41,11 +41,11 @@ //| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must //| be 8 bit unsigned or 16 bit signed. //| -//| .. class:: WaveFile(filename) +//| .. class:: WaveFile(file) //| //| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`. //| -//| :param bytes-like file: Already opened wave file +//| :param typing.BinaryIO file: Already opened wave file //| //| Playing a wave file from flash:: //| @@ -92,6 +92,12 @@ STATIC mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_deinit_obj, audioio_wavefile_deinit); +STATIC void check_for_deinit(audioio_wavefile_obj_t *self) { + if (common_hal_audioio_wavefile_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -118,14 +124,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4, //| STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_sample_rate(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_sample_rate_obj, audioio_wavefile_obj_get_sample_rate); STATIC mp_obj_t audioio_wavefile_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + check_for_deinit(self); common_hal_audioio_wavefile_set_sample_rate(self, mp_obj_get_int(sample_rate)); return mp_const_none; } @@ -144,7 +150,7 @@ const mp_obj_property_t audioio_wavefile_sample_rate_obj = { //| STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample); @@ -162,7 +168,7 @@ const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = { //| STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self)); } MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 374268e3d..0a3b03f51 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -42,7 +42,7 @@ //| :class:`I2C` --- Two wire serial protocol //| ------------------------------------------ //| -//| .. class:: I2C(scl, sda, \*, frequency=400000) +//| .. class:: I2C(scl, sda, *, frequency=400000, timeout) //| //| I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data @@ -69,13 +69,12 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); self->base.type = &bitbangio_i2c_type; shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; } -//| .. method:: I2C.deinit() +//| .. method:: deinit() //| //| Releases control of the underlying hardware so other classes can use it. //| @@ -86,13 +85,19 @@ STATIC mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_deinit_obj, bitbangio_i2c_obj_deinit); -//| .. method:: I2C.__enter__() +STATIC void check_for_deinit(bitbangio_i2c_obj_t *self) { + if (shared_module_bitbangio_i2c_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() //| //| No-op used in Context Managers. //| // Provided by context manager helper. -//| .. method:: I2C.__exit__() +//| .. method:: __exit__() //| //| Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info. @@ -110,7 +115,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) { } } -//| .. method:: I2C.scan() +//| .. method:: scan() //| //| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of //| those that respond. A device responds if it pulls the SDA line low after @@ -118,7 +123,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) { //| STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + check_for_deinit(self); check_lock(self); mp_obj_t list = mp_obj_new_list(0, NULL); // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved @@ -132,30 +137,30 @@ STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan); -//| .. method:: I2C.try_lock() +//| .. method:: try_lock() //| //| Attempts to grab the I2C lock. Returns True on success. //| STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock); -//| .. method:: I2C.unlock() +//| .. method:: unlock() //| //| Releases the I2C lock. //| STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + check_for_deinit(self); shared_module_bitbangio_i2c_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); -//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer)) +//| .. method:: readfrom_into(address, buffer, *, start=0, end=None) //| //| Read into ``buffer`` from the slave specified by ``address``. //| The number of bytes read will be the length of ``buffer``. @@ -179,7 +184,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + check_for_deinit(self); 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); check_lock(self); @@ -203,7 +208,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_readfrom_into); -//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True) +//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True) //| //| Write the bytes from ``buffer`` to the slave specified by ``address``. //| Transmits a stop bit if ``stop`` is set. @@ -232,7 +237,7 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self)); + check_for_deinit(self); check_lock(self); 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); diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c index a3c53d2a5..73bedcd8d 100644 --- a/shared-bindings/bitbangio/OneWire.c +++ b/shared-bindings/bitbangio/OneWire.c @@ -91,6 +91,12 @@ STATIC mp_obj_t bitbangio_onewire_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire_deinit); +STATIC void check_for_deinit(bitbangio_onewire_obj_t *self) { + if (shared_module_bitbangio_onewire_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -115,7 +121,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4, //| STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self)); } @@ -130,7 +136,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_res //| STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self)); } @@ -142,7 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_ //| STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self)); + check_for_deinit(self); shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); return mp_const_none; diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 974ec99e2..88bd3d6cb 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -84,7 +84,7 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, return (mp_obj_t)self; } -//| .. method:: SPI.deinit() +//| .. method:: deinit() //| //| Turn off the SPI bus. //| @@ -95,13 +95,19 @@ STATIC mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_deinit_obj, bitbangio_spi_obj_deinit); -//| .. method:: SPI.__enter__() +STATIC void check_for_deinit(bitbangio_spi_obj_t *self) { + if (shared_module_bitbangio_spi_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() //| //| No-op used by Context Managers. //| // Provided by context manager helper. -//| .. method:: SPI.__exit__() +//| .. method:: __exit__() //| //| Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info. @@ -120,7 +126,7 @@ static void check_lock(bitbangio_spi_obj_t *self) { } } -//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8) +//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8) //| //| Configures the SPI bus. Only valid when locked. //| @@ -139,7 +145,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, }; bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -162,7 +168,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, } MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configure); -//| .. method:: SPI.try_lock() +//| .. method:: try_lock() //| //| Attempts to grab the SPI lock. Returns True on success. //| @@ -171,24 +177,24 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu //| STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock); -//| .. method:: SPI.unlock() +//| .. method:: unlock() //| //| Releases the SPI lock. //| STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); shared_module_bitbangio_spi_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); -//| .. method:: SPI.write(buf) +//| .. method:: write(buf) //| //| Write the data contained in ``buf``. Requires the SPI being locked. //| If the buffer is empty, nothing happens. @@ -196,7 +202,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); mp_buffer_info_t src; mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ); if (src.len == 0) { @@ -212,7 +218,7 @@ STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) { MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write); -//| .. method:: SPI.readinto(buf) +//| .. method:: readinto(buf) //| //| Read into the buffer specified by ``buf`` while writing zeroes. //| Requires the SPI being locked. @@ -221,7 +227,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write); // TODO(tannewt): Add support for start and end kwargs. STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); if (bufinfo.len == 0) { @@ -236,7 +242,7 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_spi_readinto); -//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in)) +//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None) //| //| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``. //| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]`` @@ -246,9 +252,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_ //| :param bytearray buffer_out: Write out the data in this buffer //| :param bytearray buffer_in: Read data into this buffer //| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]`` -//| :param int out_end: End of the slice; this index is not included +//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)`` //| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` -//| :param int in_end: End of the slice; this index is not included +//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)`` //| STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; @@ -261,7 +267,7 @@ STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_ { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self)); + check_for_deinit(self); 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); diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c index 226c011a3..7367da535 100644 --- a/shared-bindings/bleio/Address.c +++ b/shared-bindings/bleio/Address.c @@ -33,13 +33,6 @@ #include "shared-bindings/bleio/Address.h" #include "shared-module/bleio/Address.h" -#define ADDRESS_BYTE_LEN 12 - -STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { - return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4); -} - - //| .. currentmodule:: bleio //| //| :class:`Address` -- BLE address @@ -48,30 +41,24 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { //| Encapsulates the address of a BLE device. //| -//| .. class:: Address(address) +//| .. class:: Address(address, address_type) //| //| Create a new Address object encapsulating the address value. //| The value itself can be one of: //| -//| :param buf: The address value to encapsulate -//| - a buffer object (bytearray, bytes) of 6 bytes -//| -//| :param address: The address to encapsulate +//| :param buf address: The address value to encapsulate. A buffer object (bytearray, bytes) of 6 bytes. +//| :param int address_type: one of these integers: +//| - `bleio.Address.PUBLIC` = 0 +//| - `bleio.Address.RANDOM_STATIC` = 1 +//| - `bleio.Address.RANDOM_PRIVATE_RESOLVABLE` = 2 +//| - `bleio.Address.RANDOM_PRIVATE_NON_RESOLVABLE` = 3 //| -//| .. attribute:: type -//| -//| The address type. One of: -//| -//| - `bleio.AddressType.PUBLIC` -//| - `bleio.AddressType.RANDOM_STATIC` -//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE` -//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE` -//| STATIC mp_obj_t bleio_address_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_address }; + enum { ARG_address, ARG_address_type }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_address, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_address_type, MP_ARG_INT, {.u_int = BLEIO_ADDRESS_TYPE_PUBLIC } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -79,44 +66,54 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); self->base.type = &bleio_address_type; - self->type = ADDRESS_PUBLIC; const mp_obj_t address = args[ARG_address].u_obj; - mp_buffer_info_t buf_info; mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); - if (buf_info.len != BLEIO_ADDRESS_BYTES) { - mp_raise_ValueError_varg(translate("Address must be %d bytes long"), BLEIO_ADDRESS_BYTES); + if (buf_info.len != NUM_BLEIO_ADDRESS_BYTES) { + mp_raise_ValueError_varg(translate("Address must be %d bytes long"), NUM_BLEIO_ADDRESS_BYTES); } - for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { - self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b]; + memcpy(self->bytes, buf_info.buf, buf_info.len); + + const mp_int_t address_type = args[ARG_address_type].u_int; + if (address_type < BLEIO_ADDRESS_TYPE_MIN || address_type > BLEIO_ADDRESS_TYPE_MAX) { + mp_raise_ValueError(translate("Address type out of range")); } + self->type = address_type; + return MP_OBJ_FROM_PTR(self); } -STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +//| .. attribute:: address_bytes +//| +//| The bytes that make up the device address (read-only) +//| +//| - `bleio.Address.PUBLIC` +//| - `bleio.Address.RANDOM_STATIC` +//| - `bleio.Address.RANDOM_PRIVATE_RESOLVABLE` +//| - `bleio.Address.RANDOM_PRIVATE_NON_RESOLVABLE` +//| +STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "Address('%02x:%02x:%02x:%02x:%02x:%02x')", - self->value[5], self->value[4], self->value[3], - self->value[2], self->value[1], self->value[0]); + return mp_obj_new_bytes(self->bytes, NUM_BLEIO_ADDRESS_BYTES); } +MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_address_bytes_obj, bleio_address_get_address_bytes); +//| .. attribute:: type +//| +//| The address type (read-only). One of these integers: +//| +//| - `bleio.Address.PUBLIC` +//| - `bleio.Address.RANDOM_STATIC` +//| - `bleio.Address.RANDOM_PRIVATE_RESOLVABLE` +//| - `bleio.Address.RANDOM_PRIVATE_NON_RESOLVABLE` +//| STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->type == ADDRESS_PUBLIC) { - return (mp_obj_t)&bleio_addresstype_public_obj; - } else if (self->type == ADDRESS_RANDOM_STATIC) { - return (mp_obj_t)&bleio_addresstype_random_static_obj; - } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) { - return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj; - } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) { - return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj; - } - - return mp_const_none; + return MP_OBJ_NEW_SMALL_INT(self->type); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type); @@ -128,7 +125,14 @@ const mp_obj_property_t bleio_address_type_obj = { }; STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_get_address_bytes_obj) }, + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_get_type_obj) }, + // These match the BLE_GAP_ADDR_TYPES values used by the nRF library. + { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_OBJ_NEW_SMALL_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) }, + }; STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table); @@ -136,7 +140,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict const mp_obj_type_t bleio_address_type = { { &mp_type_type }, .name = MP_QSTR_Address, - .print = bleio_address_print, .make_new = bleio_address_make_new, .locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict }; diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h index 9c9e20968..ef84d7432 100644 --- a/shared-bindings/bleio/Address.h +++ b/shared-bindings/bleio/Address.h @@ -29,6 +29,14 @@ #include "py/objtype.h" +#define BLEIO_ADDRESS_TYPE_PUBLIC (0) +#define BLEIO_ADDRESS_TYPE_RANDOM_STATIC (1) +#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE (2) +#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE (3) + +#define BLEIO_ADDRESS_TYPE_MIN BLEIO_ADDRESS_TYPE_PUBLIC +#define BLEIO_ADDRESS_TYPE_MAX BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + extern const mp_obj_type_t bleio_address_type; #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c deleted file mode 100644 index cf2151c94..000000000 --- a/shared-bindings/bleio/AddressType.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Artur Pacholec - * - * 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/bleio/AddressType.h" - -//| .. currentmodule:: bleio -//| -//| :class:`AddressType` -- defines the type of a BLE address -//| ============================================================= -//| -//| .. class:: bleio.AddressType -//| -//| Enum-like class to define the type of a BLE address, see also `bleio.Address`. -//| -//| .. data:: PUBLIC -//| -//| The address is public -//| -//| .. data:: RANDOM_STATIC -//| -//| The address is random static -//| -//| .. data:: RANDOM_PRIVATE_RESOLVABLE -//| -//| The address is random private resolvable -//| -//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE -//| -//| The address is private non-resolvable -//| -const mp_obj_type_t bleio_addresstype_type; - -const bleio_addresstype_obj_t bleio_addresstype_public_obj = { - { &bleio_addresstype_type }, -}; - -const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = { - { &bleio_addresstype_type }, -}; - -const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = { - { &bleio_addresstype_type }, -}; - -const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = { - { &bleio_addresstype_type }, -}; - -STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) }, - { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table); - -STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr type = MP_QSTR_PUBLIC; - - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) { - type = MP_QSTR_RANDOM_STATIC; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) { - type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE; - } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) { - type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE; - } - - mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type); -} - -const mp_obj_type_t bleio_addresstype_type = { - { &mp_type_type }, - .name = MP_QSTR_AddressType, - .print = bleio_addresstype_print, - .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict, -}; diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c index c368de361..a1dc663fd 100644 --- a/shared-bindings/bleio/CharacteristicBuffer.c +++ b/shared-bindings/bleio/CharacteristicBuffer.c @@ -47,7 +47,7 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| //| Accumulates a Characteristic's incoming values in a FIFO buffer. //| -//| .. class:: CharacteristicBuffer(Characteristic, *, timeout=1, buffer_size=64) +//| .. class:: CharacteristicBuffer(characteristic, *, timeout=1, buffer_size=64) //| //| Create a new Characteristic object identified by the specified UUID. //| @@ -92,6 +92,12 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, return MP_OBJ_FROM_PTR(self); } +STATIC void check_for_deinit(bleio_characteristic_buffer_obj_t *self) { + if (common_hal_bleio_characteristic_buffer_deinited(self)) { + raise_deinited_error(); + } +} + // These are standard stream methods. Code is in py/stream.c. // //| .. method:: read(nbytes=None) @@ -122,7 +128,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, // These three methods are used by the shared stream methods. STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + check_for_deinit(self); raise_error_if_not_connected(self); byte *buf = buf_in; @@ -141,7 +147,7 @@ STATIC mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + check_for_deinit(self); raise_error_if_not_connected(self); if (!common_hal_bleio_characteristic_buffer_connected(self)) { mp_raise_ValueError(translate("Not connected")); @@ -170,7 +176,7 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r //| STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self)); } MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting); @@ -188,7 +194,7 @@ const mp_obj_property_t bleio_characteristic_buffer_in_waiting_obj = { //| STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self)); + check_for_deinit(self); common_hal_bleio_characteristic_buffer_clear_rx_buffer(self); return mp_const_none; } diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c index 1d657635f..ca703bd53 100644 --- a/shared-bindings/bleio/Peripheral.c +++ b/shared-bindings/bleio/Peripheral.c @@ -35,7 +35,6 @@ #include "py/runtime.h" #include "shared-bindings/bleio/Adapter.h" -#include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/Peripheral.h" #include "shared-bindings/bleio/Service.h" diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c index 67e4a38c0..475bade15 100644 --- a/shared-bindings/bleio/ScanEntry.c +++ b/shared-bindings/bleio/ScanEntry.c @@ -43,94 +43,21 @@ //| ========================================================= //| //| Encapsulates information about a device that was received as a -//| response to a BLE scan request. +//| response to a BLE scan request. This object may only be created +//| by a `bleio.Scanner`: it has no user-visible constructor. //| //| .. attribute:: address //| -//| The address of the device. (read-only) -//| This attribute is of type `bleio.Address`. +//| The address of the device (read-only), of type `bleio.Address`. //| - -//| .. attribute:: manufacturer_specific_data -//| -//| The manufacturer-specific data present in the advertisement packet. (read-only) -//| - -//| .. attribute:: name -//| -//| The name of the device. (read-only) -//| Will be be `None` if the data was missing from the advertisement packet. -//| - -//| .. attribute:: raw_data -//| -//| All the advertisement data present in the packet. (read-only) -//| - -//| .. attribute:: rssi -//| -//| The signal strength of the device at the time of the scan. (read-only) -//| - -//| .. attribute:: service_uuids -//| -//| The address of the device. (read-only) -//| This attribute is a list of `bleio.UUID`. -//| This attribute might be empty or incomplete, depending on the advertisement packet. -//| Currently only 16-bit UUIDS are listed. -//| - -//| .. attribute:: tx_power_level -//| -//| The transmit power level of the device. (read-only) -//| Will be `None` if the data was missing from the advertisement packet. -//| -static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) { - uint16_t i = 0; - while (i < data_in->len) { - const uint8_t item_len = ((uint8_t*)data_in->items)[i]; - const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1]; - if (item_type != type) { - i += (item_len + 1); - continue; - } - - *data_out = &((uint8_t*)data_in->items)[i + 2]; - - return item_len; - } - - return 0; -} - -STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in); - -STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in; - mp_printf(print, "ScanEntry(address: %02x:%02x:%02x:%02x:%02x:%02x", - self->address.value[5], self->address.value[4], self->address.value[3], - self->address.value[1], self->address.value[1], self->address.value[0]); - - const mp_obj_t name_obj = scanentry_get_name(self_in); - if (name_obj != mp_const_none) { - mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj); - mp_printf(print, " name: %s", str->data); - } - - mp_print_str(print, ")"); -} - STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj); - bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); - + bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); + memcpy(address->bytes, self->address.bytes, NUM_BLEIO_ADDRESS_BYTES); address->type = self->address.type; - memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES); - - return obj; + return MP_OBJ_TO_PTR(address); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address); @@ -141,75 +68,13 @@ const mp_obj_property_t bleio_scanentry_address_obj = { (mp_obj_t)&mp_const_none_obj }, }; -STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) { - bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); - uint8_t *manuf_data; - - const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data); - if (manuf_data_len == 0) { - return mp_const_none; - } - - return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data); - -const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) { - bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); - uint8_t *name; - - // Try for Complete but settle for Shortened - uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name); - if (name_len == 0) { - name_len = find_data_item(data, AdShortenedLocalName, &name); - } - - if (name_len == 0) { - return mp_const_none; - } - - return mp_obj_new_str((const char*)name, name_len - 1); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name); - -const mp_obj_property_t bleio_scanentry_name_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - +//| .. attribute:: raw_data +//| +//| All the advertisement data present in the packet, returned as a ``bytes`` object. (read-only) +//| STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_obj_t entries = mp_obj_new_list(0, NULL); - - mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); - - uint16_t i = 0; - while (i < data->len) { - mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - - const uint8_t item_len = ((uint8_t*)data->items)[i]; - const uint8_t item_type = ((uint8_t*)data->items)[i + 1]; - - entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type); - entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]); - mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry)); - - i += (item_len + 1); - } - - return entries; + return self->data; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data); @@ -220,6 +85,10 @@ const mp_obj_property_t bleio_scanentry_raw_data_obj = { (mp_obj_t)&mp_const_none_obj }, }; +//| .. attribute:: rssi +//| +//| The signal strength of the device at the time of the scan, in integer dBm. (read-only) +//| STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -234,68 +103,10 @@ const mp_obj_property_t bleio_scanentry_rssi_obj = { (mp_obj_t)&mp_const_none_obj }, }; -STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) { - bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); - uint8_t *uuids; - - // Try for Complete but settle for Incomplete - uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids); - if (uuids_len == 0) { - uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids); - } - - mp_obj_t entries = mp_obj_new_list(0, NULL); - for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) { - const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8)); - const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, &uuid_int, NULL); - - mp_obj_list_append(entries, uuid_obj); - } - - // TODO: 32-bit UUIDs - // TODO: 128-bit UUIDs - - return entries; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids); - -const mp_obj_property_t bleio_scanentry_service_uuids_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - -STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) { - bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); - uint8_t *tx_power; - - const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power); - if (tx_power_len == 0) { - return mp_const_none; - } - - return mp_obj_new_int((int8_t)(*tx_power)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level); - -const mp_obj_property_t bleio_scanentry_tx_power_level_obj = { - .base.type = &mp_type_property, - .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj }, -}; - STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) }, - { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) }, - { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) }, - { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) }, - { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) }, - { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) }, - { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) }, + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table); @@ -303,6 +114,5 @@ STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_ const mp_obj_type_t bleio_scanentry_type = { { &mp_type_type }, .name = MP_QSTR_ScanEntry, - .print = bleio_scanentry_print, .locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict }; diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c index 5615ce103..a249d5343 100644 --- a/shared-bindings/bleio/Scanner.c +++ b/shared-bindings/bleio/Scanner.c @@ -80,8 +80,8 @@ STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_m enum { ARG_timeout, ARG_interval, ARG_window }; static const mp_arg_t allowed_args[] = { { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c index d054ea719..f79dfa675 100644 --- a/shared-bindings/bleio/UUID.c +++ b/shared-bindings/bleio/UUID.c @@ -47,10 +47,11 @@ //| The value can be one of: //| //| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID) -//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) +//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID) //| - a string of hex digits of the form 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' //| //| :param value: The uuid value to encapsulate +//| :type value: int or typing.ByteString //| STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_arg_check_num(n_args, kw_args, 1, 1, false); @@ -125,6 +126,8 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co //| //| The 16-bit part of the UUID. (read-only) //| +//| :type: int +//| STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self)); @@ -141,9 +144,11 @@ const mp_obj_property_t bleio_uuid_uuid16_obj = { //| .. attribute:: uuid128 //| -//| The 128-bit value of the UUID, returned as bytes. +//| The 128-bit value of the UUID //| Raises AttributeError if this is a 16-bit UUID. (read-only) //| +//| :type: bytes +//| STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -165,9 +170,10 @@ const mp_obj_property_t bleio_uuid_uuid128_obj = { //| .. attribute:: size //| -//| Returns 128 if this UUID represents a 128-bit vendor-specific UUID. -//| Returns 16 if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only) -//| 32-bit UUIDs are not currently supported. +//| 128 if this UUID represents a 128-bit vendor-specific UUID. 16 if this UUID represents a +//| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported. +//| +//| :type: int //| STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 4b98e4673..06c00d588 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -27,7 +27,6 @@ #include "shared-bindings/bleio/__init__.h" #include "shared-bindings/bleio/Address.h" -#include "shared-bindings/bleio/AddressType.h" #include "shared-bindings/bleio/Characteristic.h" #include "shared-bindings/bleio/CharacteristicBuffer.h" #include "shared-bindings/bleio/Descriptor.h" @@ -52,7 +51,6 @@ //| :maxdepth: 3 //| //| Address -//| AddressType //| AdvertisementData //| Adapter //| Characteristic @@ -87,9 +85,6 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, - - // Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index 82a0cab67..47e2d64bc 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -34,7 +34,6 @@ //| //| .. module:: board //| :synopsis: Board specific pin names -//| :platform: SAMD21 //| //| Common container for board base pin names. These will vary from board to //| board so don't expect portability when using this module. @@ -42,7 +41,7 @@ //| .. warning:: The board module varies by board. The APIs documented here may or may not be //| available on a specific board. -//| .. method:: I2C() +//| .. function:: I2C() //| //| Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton. //| @@ -66,7 +65,7 @@ mp_obj_t board_i2c(void) { MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); -//| .. method:: SPI() +//| .. function:: SPI() //| //| Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a //| singleton. @@ -90,7 +89,7 @@ mp_obj_t board_spi(void) { #endif MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); -//| .. method:: UART() +//| .. function:: UART() //| //| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton. //| diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index e17a72b48..0e639f0b5 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -41,7 +41,7 @@ //| :class:`I2C` --- Two wire serial protocol //| ------------------------------------------ //| -//| .. class:: I2C(scl, sda, \*, frequency=400000) +//| .. class:: I2C(scl, sda, *, frequency=400000, timeout=255) //| //| I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data @@ -82,7 +82,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con return (mp_obj_t)self; } -//| .. method:: I2C.deinit() +//| .. method:: deinit() //| //| Releases control of the underlying hardware so other classes can use it. //| @@ -93,13 +93,19 @@ STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit); -//| .. method:: I2C.__enter__() +STATIC void check_for_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() //| //| No-op used in Context Managers. //| // Provided by context manager helper. -//| .. method:: I2C.__exit__() +//| .. method:: __exit__() //| //| Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info. @@ -118,7 +124,7 @@ static void check_lock(busio_i2c_obj_t *self) { } } -//| .. method:: I2C.scan() +//| .. method:: scan() //| //| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a //| list of those that respond. @@ -128,7 +134,7 @@ static void check_lock(busio_i2c_obj_t *self) { //| STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + check_for_deinit(self); check_lock(self); mp_obj_t list = mp_obj_new_list(0, NULL); // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved @@ -142,7 +148,7 @@ STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); -//| .. method:: I2C.try_lock() +//| .. method:: try_lock() //| //| Attempts to grab the I2C lock. Returns True on success. //| @@ -151,24 +157,24 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); //| STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_busio_i2c_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); -//| .. method:: I2C.unlock() +//| .. method:: unlock() //| //| Releases the I2C lock. //| STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + check_for_deinit(self); common_hal_busio_i2c_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); -//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer)) +//| .. method:: readfrom_into(address, buffer, *, start=0, end=None) //| //| Read into ``buffer`` from the slave specified by ``address``. //| The number of bytes read will be the length of ``buffer``. @@ -181,7 +187,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| :param int address: 7-bit device address //| :param bytearray buffer: buffer to write into //| :param int start: Index to start writing at -//| :param int end: Index to write up to but not include +//| :param int end: Index to write up to but not include. Defaults to ``len(buffer)`` //| STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; @@ -192,7 +198,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -216,7 +222,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, } MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_into); -//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True) +//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True) //| //| Write the bytes from ``buffer`` to the slave specified by ``address``. //| Transmits a stop bit if ``stop`` is set. @@ -231,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_in //| :param int address: 7-bit device address //| :param bytearray buffer: buffer containing the bytes to write //| :param int start: Index to start writing from -//| :param int end: Index to read up to but not include +//| :param int end: Index to read up to but not include. Defaults to ``len(buffer)`` //| :param bool stop: If true, output an I2C stop condition after the //| buffer is written //| @@ -245,7 +251,7 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_i2c_deinited(self)); + check_for_deinit(self); check_lock(self); 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); diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c index ceba4f8ee..aca2a3ef2 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/busio/OneWire.c @@ -91,6 +91,12 @@ STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit); +STATIC void check_for_deinit(busio_onewire_obj_t *self) { + if (common_hal_busio_onewire_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -118,7 +124,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, bus //| STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_busio_onewire_reset(self)); } @@ -133,7 +139,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); //| STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self)); } @@ -145,7 +151,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit //| STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_onewire_deinited(self)); + check_for_deinit(self); common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); return mp_const_none; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index f690eea18..a7d7d515c 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -95,7 +95,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con return (mp_obj_t)self; } -//| .. method:: SPI.deinit() +//| .. method:: deinit() //| //| Turn off the SPI bus. //| @@ -106,13 +106,13 @@ STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit); -//| .. method:: SPI.__enter__() +//| .. method:: __enter__() //| //| No-op used by Context Managers. //| // Provided by context manager helper. -//| .. method:: SPI.__exit__() +//| .. method:: __exit__() //| //| Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info. @@ -124,14 +124,20 @@ STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__); -static void check_lock(busio_spi_obj_t *self) { +STATIC void check_lock(busio_spi_obj_t *self) { asm(""); if (!common_hal_busio_spi_has_lock(self)) { mp_raise_RuntimeError(translate("Function requires lock")); } } -//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8) +STATIC void check_for_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8) //| //| Configures the SPI bus. The SPI object must be locked. //| @@ -162,7 +168,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_ { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -188,7 +194,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_ } MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); -//| .. method:: SPI.try_lock() +//| .. method:: try_lock() //| //| Attempts to grab the SPI lock. Returns True on success. //| @@ -197,31 +203,30 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); //| STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); return mp_obj_new_bool(common_hal_busio_spi_try_lock(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); -//| .. method:: SPI.unlock() +//| .. method:: unlock() //| //| Releases the SPI lock. //| STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); common_hal_busio_spi_unlock(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); -//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer)) +//| .. method:: write(buffer, *, start=0, end=None) //| //| Write the data contained in ``buffer``. The SPI object must be locked. //| If the buffer is empty, nothing happens. //| //| :param bytearray buffer: Write out the data in this buffer //| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]`` -//| :param int end: End of the slice; this index is not included +//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; @@ -231,7 +236,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -255,7 +260,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write); -//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0) +//| .. method:: readinto(buffer, *, start=0, end=None, write_value=0) //| //| Read into ``buffer`` while writing ``write_value`` for each byte read. //| The SPI object must be locked. @@ -263,7 +268,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write); //| //| :param bytearray buffer: Read data into this buffer //| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]`` -//| :param int end: End of the slice; this index is not included +//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| :param int write_value: Value to write while reading. (Usually ignored.) //| STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -275,7 +280,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -298,7 +303,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m } MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto); -//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in)) +//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None) //| //| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``. //| The SPI object must be locked. @@ -309,9 +314,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto); //| :param bytearray buffer_out: Write out the data in this buffer //| :param bytearray buffer_in: Read data into this buffer //| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]`` -//| :param int out_end: End of the slice; this index is not included +//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)`` //| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]`` -//| :param int in_end: End of the slice; this index is not included +//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)`` //| STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; @@ -324,7 +329,7 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); check_lock(self); 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); @@ -367,7 +372,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 2, busio_spi_write_read //| STATIC mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_spi_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_get_frequency(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequency); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 94ad1bd3e..c7eef8c43 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -46,7 +46,7 @@ //| ================================================= //| //| -//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64) +//| .. class:: UART(tx, rx, *, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64) //| //| A common bidirectional serial protocol that uses an an agreed upon speed //| rather than a shared clock line. @@ -137,6 +137,12 @@ STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit); +STATIC void check_for_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -196,7 +202,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ // These three methods are used by the shared stream methods. STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); byte *buf = buf_in; // make sure we want at least 1 char @@ -209,7 +215,7 @@ STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); const byte *buf = buf_in; return common_hal_busio_uart_write(self, buf, size, errcode); @@ -217,7 +223,7 @@ STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); mp_uint_t ret; if (request == MP_IOCTL_POLL) { mp_uint_t flags = arg; @@ -241,14 +247,14 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t //| STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_get_baudrate(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_baudrate_obj, busio_uart_obj_get_baudrate); STATIC mp_obj_t busio_uart_obj_set_baudrate(mp_obj_t self_in, mp_obj_t baudrate) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); common_hal_busio_uart_set_baudrate(self, mp_obj_get_int(baudrate)); return mp_const_none; } @@ -268,7 +274,7 @@ const mp_obj_property_t busio_uart_baudrate_obj = { //| STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self)); } MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting); @@ -286,13 +292,13 @@ const mp_obj_property_t busio_uart_in_waiting_obj = { //| STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + check_for_deinit(self); common_hal_busio_uart_clear_rx_buffer(self); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); -//| .. class:: busio.UART.Parity +//| .. class:: busio.UART.Parity() //| //| Enum-like class to define the parity used to verify correct data transfer. //| diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c index 958ee062a..ff2933dc6 100644 --- a/shared-bindings/busio/__init__.c +++ b/shared-bindings/busio/__init__.c @@ -35,7 +35,6 @@ #include "shared-bindings/busio/OneWire.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/busio/UART.h" -#include "shared-bindings/busio/__init__.h" #include "py/runtime.h" diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 1ced15137..6587ee7ea 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -105,6 +105,12 @@ STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_ } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); +STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + raise_deinited_error(); + } +} + //| //| .. method:: switch_to_output(value=False, drive_mode=digitalio.DriveMode.PUSH_PULL) //| @@ -121,7 +127,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_ { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_drive_mode_push_pull_obj} }, }; digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); 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); @@ -158,7 +164,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_o { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, }; digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); 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); @@ -191,7 +197,7 @@ extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_o STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self); if (direction == DIRECTION_INPUT) { return (mp_obj_t)&digitalio_direction_input_obj; @@ -202,7 +208,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_di STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_obj_t value) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (value == &digitalio_direction_input_obj) { common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE); } else if (value == &digitalio_direction_output_obj) { @@ -227,7 +233,7 @@ const mp_obj_property_t digitalio_digitalio_direction_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); bool value = common_hal_digitalio_digitalinout_get_value(self); return mp_obj_new_bool(value); } @@ -235,7 +241,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digita STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError(translate("Cannot set value when direction is input.")); return mp_const_none; @@ -261,7 +267,7 @@ const mp_obj_property_t digitalio_digitalinout_value_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError(translate("Drive mode not used when direction is input.")); return mp_const_none; @@ -276,7 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_d STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) { mp_raise_AttributeError(translate("Drive mode not used when direction is input.")); return mp_const_none; @@ -309,7 +315,7 @@ const mp_obj_property_t digitalio_digitalio_drive_mode_obj = { //| STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { mp_raise_AttributeError(translate("Pull not used when direction is output.")); return mp_const_none; @@ -326,7 +332,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digital STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self)); + check_for_deinit(self); if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) { mp_raise_AttributeError(translate("Pull not used when direction is output.")); return mp_const_none; @@ -381,7 +387,6 @@ digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj) { mp_raise_TypeError(translate("argument num/types mismatch")); } digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj); - raise_error_if_deinited( - common_hal_digitalio_digitalinout_deinited(pin)); + check_for_deinit(pin); return pin; } diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 3136ae88a..5a027561b 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -53,12 +53,13 @@ void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); 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, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 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, uint32_t* pixels, uint32_t length); +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); diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 6d18ac78f..6ba4914a0 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -64,7 +64,7 @@ //| :param int height: Height of the grid in tiles. //| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. //| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. -//| :param in default_tile: Default tile index to show. +//| :param int default_tile: Default tile index to show. //| :param int x: Initial x position of the left edge within the parent. //| :param int y: Initial y position of the top edge within the parent. //| @@ -196,6 +196,83 @@ const mp_obj_property_t displayio_tilegrid_y_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: flip_x +//| +//| If true, the left edge rendered will be the right edge of the right-most tile. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_flip_x(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_x_obj, displayio_tilegrid_obj_get_flip_x); + +STATIC mp_obj_t displayio_tilegrid_obj_set_flip_x(mp_obj_t self_in, mp_obj_t flip_x_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_flip_x(self, mp_obj_is_true(flip_x_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_x_obj, displayio_tilegrid_obj_set_flip_x); + +const mp_obj_property_t displayio_tilegrid_flip_x_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_x_obj, + (mp_obj_t)&displayio_tilegrid_set_flip_x_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: flip_y +//| +//| If true, the top edge rendered will be the bottom edge of the bottom-most tile. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_flip_y(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_y_obj, displayio_tilegrid_obj_get_flip_y); + +STATIC mp_obj_t displayio_tilegrid_obj_set_flip_y(mp_obj_t self_in, mp_obj_t flip_y_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_flip_y(self, mp_obj_is_true(flip_y_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_y_obj, displayio_tilegrid_obj_set_flip_y); + +const mp_obj_property_t displayio_tilegrid_flip_y_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_y_obj, + (mp_obj_t)&displayio_tilegrid_set_flip_y_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. attribute:: transpose_xy +//| +//| If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree +//| rotation can be achieved along with the corresponding mirrored version. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_transpose_xy_obj, displayio_tilegrid_obj_get_transpose_xy); + +STATIC mp_obj_t displayio_tilegrid_obj_set_transpose_xy(mp_obj_t self_in, mp_obj_t transpose_xy_obj) { + displayio_tilegrid_t *self = native_tilegrid(self_in); + + common_hal_displayio_tilegrid_set_transpose_xy(self, mp_obj_is_true(transpose_xy_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_transpose_xy_obj, displayio_tilegrid_obj_set_transpose_xy); + +const mp_obj_property_t displayio_tilegrid_transpose_xy_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_transpose_xy_obj, + (mp_obj_t)&displayio_tilegrid_set_transpose_xy_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. attribute:: pixel_shader //| //| The pixel shader of the tilegrid. @@ -292,6 +369,9 @@ STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_tilegrid_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_tilegrid_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_flip_x), MP_ROM_PTR(&displayio_tilegrid_flip_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_flip_y), MP_ROM_PTR(&displayio_tilegrid_flip_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_transpose_xy), MP_ROM_PTR(&displayio_tilegrid_transpose_xy_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_locals_dict_table); diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index 15a71b53b..1f9995a94 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -42,6 +42,14 @@ void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y) mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self); void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader); + +bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x); +bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y); +bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy); + uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self); uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 44b1e0b07..9dc17103b 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -69,7 +69,7 @@ //| -//| .. method:: release_displays() +//| .. function:: release_displays() //| //| 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 diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index 908cb307d..e2b924c07 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -109,6 +109,12 @@ STATIC mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_deinit_obj, frequencyio_frequencyin_deinit); +STATIC void check_for_deinit(frequencyio_frequencyin_obj_t *self) { + if (common_hal_frequencyio_frequencyin_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -133,7 +139,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj, //| STATIC mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); common_hal_frequencyio_frequencyin_pause(self); return mp_const_none; @@ -146,7 +152,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequen //| STATIC mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); common_hal_frequencyio_frequencyin_resume(self); return mp_const_none; @@ -160,7 +166,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_freque STATIC mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); common_hal_frequencyio_frequencyin_clear(self); return mp_const_none; @@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequen //| STATIC mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_capture_period(self)); } @@ -186,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequency_get_capture_period_obj, frequenc STATIC mp_obj_t frequencyio_frequencyin_obj_set_capture_period(mp_obj_t self_in, mp_obj_t capture_period) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); common_hal_frequencyio_frequencyin_set_capture_period(self, mp_obj_get_int(capture_period)); return mp_const_none; @@ -206,7 +212,7 @@ const mp_obj_property_t frequencyio_frequencyin_capture_period_obj = { //| STATIC mp_obj_t frequencyio_frequencyin_obj_get_value(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self)); + check_for_deinit(self); //return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_item(self)); return mp_obj_new_int_from_float(common_hal_frequencyio_frequencyin_get_item(self)); diff --git a/shared-bindings/help.c b/shared-bindings/help.c index e0770ff3c..4e7c3a78b 100644 --- a/shared-bindings/help.c +++ b/shared-bindings/help.c @@ -27,7 +27,7 @@ //| :func:`help` - Built-in method to provide helpful information //| ============================================================== //| -//| .. method:: help(object=None) +//| .. function:: help(object=None) //| //| Prints a help method about the given object. When ``object`` is none, //| prints general port information. diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index 090a53581..2598accbb 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -150,7 +150,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4 STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type)); i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_i2cslave_i2c_slave_deinited(self)); + if(common_hal_i2cslave_i2c_slave_deinited(self)) { + raise_deinited_error(); + } enum { ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index 4f2e28702..8f9bbbb31 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -53,6 +53,7 @@ Module Supported Ports `nvm` **SAMD Express** `os` **All Supported** `pulseio` **SAMD/SAMD Express** +`ps2io` **SAMD/SAMD Express** `random` **All Supported** `rotaryio` **SAMD51, SAMD Express** `storage` **All Supported** diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index e79663107..3635f0afb 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -40,7 +40,7 @@ //| //| Identifies an IO pin on the microcontroller. //| -//| .. class:: Pin +//| .. class:: Pin() //| //| Identifies an IO pin on the microcontroller. They are fixed by the //| hardware so they cannot be constructed on demand. Instead, use diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c index 7c3f84fca..913242ad2 100644 --- a/shared-bindings/microcontroller/RunMode.c +++ b/shared-bindings/microcontroller/RunMode.c @@ -31,24 +31,30 @@ //| :class:`RunMode` -- run state of the microcontroller //| ============================================================= //| -//| .. class:: microcontroller.RunMode +//| .. class:: RunMode() //| //| Enum-like class to define the run mode of the microcontroller and //| CircuitPython. //| -//| .. data:: NORMAL +//| .. attribute:: NORMAL //| //| Run CircuitPython as normal. //| -//| .. data:: SAFE_MODE +//| :type microcontroller.RunMode: +//| +//| .. attribute:: SAFE_MODE //| //| Run CircuitPython in safe mode. User code will not be run and the //| file system will be writeable over USB. //| -//| .. data:: BOOTLOADER +//| :type microcontroller.RunMode: +//| +//| .. attribute:: BOOTLOADER //| //| Run the bootloader. //| +//| :type microcontroller.RunMode: +//| const mp_obj_type_t mcu_runmode_type; const mcu_runmode_obj_t mcu_runmode_normal_obj = { diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index da8d0bd94..090c4564d 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -62,14 +62,14 @@ //| RunMode //| -//| .. attribute:: cpu +//| .. data:: cpu //| //| CPU information and control, such as ``cpu.temperature`` and ``cpu.frequency`` //| (clock frequency). //| This object is the sole instance of `microcontroller.Processor`. //| -//| .. method:: delay_us(delay) +//| .. function:: delay_us(delay) //| //| Dedicated delay method used for very short delays. **Do not** do long delays //| because this stops all other functions from completing. Think of this as an empty @@ -87,7 +87,7 @@ STATIC mp_obj_t mcu_delay_us(mp_obj_t delay_obj) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_delay_us_obj, mcu_delay_us); -//| .. method:: disable_interrupts() +//| .. function:: disable_interrupts() //| //| Disable all interrupts. Be very careful, this can stall everything. //| @@ -97,7 +97,7 @@ STATIC mp_obj_t mcu_disable_interrupts(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_disable_interrupts_obj, mcu_disable_interrupts); -//| .. method:: enable_interrupts() +//| .. function:: enable_interrupts() //| //| Enable the interrupts that were enabled at the last disable. //| @@ -107,7 +107,7 @@ STATIC mp_obj_t mcu_enable_interrupts(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_enable_interrupts_obj, mcu_enable_interrupts); -//| .. method:: on_next_reset(run_mode) +//| .. function:: on_next_reset(run_mode) //| //| Configure the run mode used the next time the microcontroller is reset but //| not powered down. @@ -132,7 +132,7 @@ STATIC mp_obj_t mcu_on_next_reset(mp_obj_t run_mode_obj) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_on_next_reset_obj, mcu_on_next_reset); -//| .. method:: reset() +//| .. function:: reset() //| //| Reset the microcontroller. After reset, the microcontroller will enter the //| run mode last set by `on_next_reset`. @@ -148,11 +148,13 @@ STATIC mp_obj_t mcu_reset(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); -//| .. attribute:: nvm +//| .. data:: nvm //| //| Available non-volatile memory. //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. //| +//| :type: nvm.ByteArray or None +//| //| :mod:`microcontroller.pin` --- Microcontroller pin names //| -------------------------------------------------------- diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index 05d6fd97a..1ee66337b 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -55,11 +55,11 @@ //| pixel_off = bytearray([0, 0, 0]) //| neopixel_write.neopixel_write(pin, pixel_off) //| -//| .. method:: neopixel_write.neopixel_write(digitalinout, buf) +//| .. function:: neopixel_write(digitalinout, buf) //| //| Write buf out on the given DigitalInOut. //| -//| :param ~digitalio.DigitalInOut gpio: the DigitalInOut to output with +//| :param ~digitalio.DigitalInOut digitalinout: the DigitalInOut to output with //| :param bytearray buf: The bytes to clock out. No assumption is made about color order //| STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c index 1067ea549..01763a73c 100644 --- a/shared-bindings/network/__init__.c +++ b/shared-bindings/network/__init__.c @@ -49,7 +49,7 @@ //| It is used by the 'socket' module to look up a suitable //| NIC when a socket is created. //| -//| .. function:: route +//| .. function:: route() //| //| Returns a list of all configured NICs. //| diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c new file mode 100644 index 000000000..fb5c24b85 --- /dev/null +++ b/shared-bindings/ps2io/Ps2.c @@ -0,0 +1,243 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> + * + * 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 <stdint.h> + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/ps2io/Ps2.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: ps2io +//| +//| :class:`Ps2` -- Communicate with a PS/2 keyboard or mouse +//| ========================================================= +//| +//| Ps2 implements the PS/2 keyboard/mouse serial protocol, used in +//| legacy devices. It is similar to UART but there are only two +//| lines (Data and Clock). PS/2 devices are 5V, so bidirectional +//| level converters must be used to connect the I/O lines to pins +//| of 3.3V boards. +//| +//| .. class:: Ps2(data_pin, clock_pin) +//| +//| Create a Ps2 object associated with the given pins. +//| +//| :param ~microcontroller.Pin data_pin: Pin tied to data wire. +//| :param ~microcontroller.Pin clock_pin: Pin tied to clock wire. +//| This pin must support interrupts. +//| +//| Read one byte from PS/2 keyboard and turn on Scroll Lock LED:: +//| +//| import ps2io +//| import board +//| +//| kbd = ps2io.Ps2(board.D10, board.D11) +//| +//| while len(kbd) == 0: +//| pass +//| +//| print(kbd.popleft()) +//| print(kbd.sendcmd(0xed)) +//| print(kbd.sendcmd(0x01)) +//| +STATIC mp_obj_t ps2io_ps2_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_datapin, ARG_clkpin }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_datapin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_clkpin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + 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); + assert_pin(args[ARG_clkpin].u_obj, false); + assert_pin(args[ARG_datapin].u_obj, false); + const mcu_pin_obj_t* clkpin = MP_OBJ_TO_PTR(args[ARG_clkpin].u_obj); + assert_pin_free(clkpin); + const mcu_pin_obj_t* datapin = MP_OBJ_TO_PTR(args[ARG_datapin].u_obj); + assert_pin_free(datapin); + + ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); + self->base.type = &ps2io_ps2_type; + + common_hal_ps2io_ps2_construct(self, datapin, clkpin); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the Ps2 and releases any hardware resources for reuse. +//| +STATIC mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_ps2io_ps2_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_deinit_obj, ps2io_ps2_deinit); + +STATIC void check_for_deinit(ps2io_ps2_obj_t *self) { + if (common_hal_ps2io_ps2_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_ps2io_ps2_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__); + +//| .. method:: popleft() +//| +//| Removes and returns the oldest received byte. When buffer +//| is empty, raises an IndexError exception. +//| +STATIC mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + int b = common_hal_ps2io_ps2_popleft(self); + if (b < 0) { + mp_raise_IndexError(translate("Pop from an empty Ps2 buffer")); + } + return MP_OBJ_NEW_SMALL_INT(b); +} +MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft); + +//| .. method:: sendcmd(byte) +//| +//| Sends a command byte to PS/2. Returns the response byte, typically +//| the general ack value (0xFA). Some commands return additional data +//| which is available through :py:func:`popleft()`. +//| +//| Raises a RuntimeError in case of failure. The root cause can be found +//| by calling :py:func:`clear_errors()`. It is advisable to call +//| :py:func:`clear_errors()` before :py:func:`sendcmd()` to flush any +//| previous errors. +//| +//| :param int byte: byte value of the command +//| +STATIC mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_int_t cmd = mp_obj_get_int(ob) & 0xff; + int resp = common_hal_ps2io_ps2_sendcmd(self, cmd); + if (resp < 0) { + mp_raise_RuntimeError(translate("Failed sending command.")); + } + return MP_OBJ_NEW_SMALL_INT(resp); +} +MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd); + +//| .. method:: clear_errors() +//| +//| Returns and clears a bitmap with latest recorded communication errors. +//| +//| Reception errors (arise asynchronously, as data is received): +//| +//| 0x01: start bit not 0 +//| +//| 0x02: timeout +//| +//| 0x04: parity bit error +//| +//| 0x08: stop bit not 1 +//| +//| 0x10: buffer overflow, newest data discarded +//| +//| Transmission errors (can only arise in the course of sendcmd()): +//| +//| 0x100: clock pin didn't go to LO in time +//| +//| 0x200: clock pin didn't go to HI in time +//| +//| 0x400: data pin didn't ACK +//| +//| 0x800: clock pin didn't ACK +//| +//| 0x1000: device didn't respond to RTS +//| +//| 0x2000: device didn't send a response byte in time +//| +STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_ps2io_ps2_clear_errors(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors); + +//| .. method:: __len__() +//| +//| Returns the number of received bytes in buffer, available +//| to :py:func:`popleft()`. +//| +STATIC mp_obj_t ps2_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + uint16_t len = common_hal_ps2io_ps2_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t ps2io_ps2_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ps2io_ps2_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&ps2io_ps2___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&ps2io_ps2_popleft_obj) }, + { MP_ROM_QSTR(MP_QSTR_sendcmd), MP_ROM_PTR(&ps2io_ps2_sendcmd_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear_errors), MP_ROM_PTR(&ps2io_ps2_clear_errors_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(ps2io_ps2_locals_dict, ps2io_ps2_locals_dict_table); + +const mp_obj_type_t ps2io_ps2_type = { + { &mp_type_type }, + .name = MP_QSTR_Ps2, + .make_new = ps2io_ps2_make_new, + .unary_op = ps2_unary_op, + .locals_dict = (mp_obj_dict_t*)&ps2io_ps2_locals_dict, +}; diff --git a/shared-bindings/ps2io/Ps2.h b/shared-bindings/ps2io/Ps2.h new file mode 100644 index 000000000..523869d55 --- /dev/null +++ b/shared-bindings/ps2io/Ps2.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> + * + * 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_PS2IO_PS2_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/ps2io/Ps2.h" + +extern const mp_obj_type_t ps2io_ps2_type; + +extern void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self, + const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin); +extern void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self); +extern bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self); +extern uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self); +extern int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self); +extern int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b); +extern uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c new file mode 100644 index 000000000..ec7c43e51 --- /dev/null +++ b/shared-bindings/ps2io/__init__.c @@ -0,0 +1,73 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> + * + * 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 <stdint.h> + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/ps2io/Ps2.h" + +//| :mod:`ps2io` --- Support for PS/2 protocol +//| ===================================================== +//| +//| .. module:: ps2io +//| :synopsis: Support for PS/2 based devices +//| :platform: SAMD21 +//| +//| The `ps2io` module contains classes to provide PS/2 communication. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Ps2 +//| + +//| .. warning:: This module is not available in some SAMD21 builds. See the +//| :ref:`module-support-matrix` for more info. +//| + +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| + +STATIC const mp_rom_map_elem_t ps2io_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ps2io) }, + { MP_ROM_QSTR(MP_QSTR_Ps2), MP_ROM_PTR(&ps2io_ps2_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(ps2io_module_globals, ps2io_module_globals_table); + +const mp_obj_module_t ps2io_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&ps2io_module_globals, +}; diff --git a/shared-bindings/ps2io/__init__.h b/shared-bindings/ps2io/__init__.h new file mode 100644 index 000000000..1ff3d97b5 --- /dev/null +++ b/shared-bindings/ps2io/__init__.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co> + * + * 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_PS2IO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index 37939a07a..40981e0a8 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -42,7 +42,7 @@ //| //| PWMOut can be used to output a PWM signal on a given pin. //| -//| .. class:: PWMOut(pin, \*, duty_cycle=0, frequency=500, variable_frequency=False) +//| .. class:: PWMOut(pin, *, duty_cycle=0, frequency=500, variable_frequency=False) //| //| Create a PWM object associated with the given pin. This allows you to //| write PWM signals out on the given pin. Frequency is fixed after init @@ -133,6 +133,12 @@ STATIC mp_obj_t pulseio_pwmout_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deinit); +STATIC void check_for_deinit(pulseio_pwmout_obj_t *self) { + if (common_hal_pulseio_pwmout_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -158,14 +164,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pu //| be half high and then half low. STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle); STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + check_for_deinit(self); mp_int_t duty = mp_obj_get_int(duty_cycle); if (duty < 0 || duty > 0xffff) { mp_raise_ValueError(translate("PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)")); @@ -189,14 +195,14 @@ const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = { //| STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self)); } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency); STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self)); + check_for_deinit(self); if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) { mp_raise_AttributeError(translate( "PWM frequency not writable when variable_frequency is False on " diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 426ac4384..8b69109f0 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -45,7 +45,7 @@ //| The pulsed signal consists of timed active and idle periods. Unlike PWM, //| there is no set duration for active and idle pairs. //| -//| .. class:: PulseIn(pin, maxlen=2, \*, idle_state=False) +//| .. class:: PulseIn(pin, maxlen=2, *, idle_state=False) //| //| Create a PulseIn object associated with the given pin. The object acts as //| a read-only sequence of pulse lengths with a given max length. When it is @@ -114,6 +114,12 @@ STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_deinit); +STATIC void check_for_deinit(pulseio_pulsein_obj_t *self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -138,7 +144,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, p //| STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); common_hal_pulseio_pulsein_pause(self); return mp_const_none; @@ -162,7 +168,7 @@ STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_ar { MP_QSTR_trigger_duration, MP_ARG_INT, {.u_int = 0} }, }; pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); 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); @@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re //| STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); common_hal_pulseio_pulsein_clear(self); return mp_const_none; @@ -191,7 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); //| STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self)); } @@ -204,7 +210,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_pople //| STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self)); } @@ -224,7 +230,7 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = { //| STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self)); } @@ -248,7 +254,7 @@ const mp_obj_property_t pulseio_pulsein_paused_obj = { //| STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); uint16_t len = common_hal_pulseio_pulsein_get_len(self); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); @@ -272,7 +278,7 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va mp_raise_AttributeError(translate("Cannot delete values")); } else { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + check_for_deinit(self); if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { mp_raise_NotImplementedError(translate("Slices not supported")); diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 493b7e2ff..172459e5d 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -127,7 +127,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, //| STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_pulseio_pulseout_deinited(self)); + if (common_hal_pulseio_pulseout_deinited(self)) { + raise_deinited_error(); + } mp_buffer_info_t bufinfo; mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ); diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c index 1114b604b..a3cec3dca 100644 --- a/shared-bindings/pulseio/__init__.c +++ b/shared-bindings/pulseio/__init__.c @@ -54,10 +54,6 @@ //| PWMOut //| -//| .. warning:: This module is not available in some SAMD21 builds. See the -//| :ref:`module-support-matrix` for more info. -//| - //| All classes change hardware state and should be deinitialized when they //| are no longer needed if the program continues after use. To do so, either //| call :py:meth:`!deinit` or use a context manager. See diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 5d2264ffc..f2f157847 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -100,6 +100,12 @@ STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit); +STATIC void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -126,7 +132,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___ //| STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self)); + check_for_deinit(self); return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self)); } @@ -134,7 +140,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio STATIC mp_obj_t rotaryio_incrementalencoder_obj_set_position(mp_obj_t self_in, mp_obj_t new_position) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self)); + check_for_deinit(self); common_hal_rotaryio_incrementalencoder_set_position(self, mp_obj_get_int(new_position)); return mp_const_none; diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c index 085d4e690..6d04a9893 100644 --- a/shared-bindings/socket/__init__.c +++ b/shared-bindings/socket/__init__.c @@ -51,7 +51,7 @@ STATIC const mp_obj_type_t socket_type; //| .. currentmodule:: socket //| -//| .. class:: socket(family, type, proto, ...) +//| .. class:: socket(family, type, proto) //| //| Create a new socket //| diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index 4db3a9fec..ba439b951 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -48,7 +48,7 @@ //| directly. //| -//| .. function:: mount(filesystem, mount_path, \*, readonly=False) +//| .. function:: mount(filesystem, mount_path, *, readonly=False) //| //| Mounts the given filesystem object at the given path. //| @@ -183,7 +183,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { //| this property can only be set when the device is writable by the //| microcontroller. //| - //| .. method:: mkfs + //| .. method:: mkfs() //| //| Format the block device, deleting any data that may have been there //| @@ -216,7 +216,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { //| //| Don't call this directly, call `storage.mount`. //| - //| .. method:: umount + //| .. method:: umount() //| //| Don't call this directly, call `storage.umount`. //| diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index 9240a15bb..ea14b3763 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -67,9 +67,9 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { } MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize); -//| .. function:: pack(fmt, v1, v2, ...) +//| .. function:: pack(fmt, *values) //| -//| Pack the values v1, v2, ... according to the format string fmt. +//| Pack the values according to the format string fmt. //| The return value is a bytes object encoding the values. //| @@ -85,9 +85,9 @@ STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack); -//| .. function:: pack_into(fmt, buffer, offset, v1, v2, ...) +//| .. function:: pack_into(fmt, buffer, offset, *values) //| -//| Pack the values v1, v2, ... according to the format string fmt into a buffer +//| Pack the values according to the format string fmt into a buffer //| starting at offset. offset may be negative to count from the end of buffer. //| diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 3babe2db4..70c01c2d8 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -47,7 +47,7 @@ //| written in MicroPython will work in CPython but not necessarily the other //| way around. //| -//| .. method:: monotonic() +//| .. function:: monotonic() //| //| Returns an always increasing value of time with an unknown reference //| point. Only use it to compare against other values from `monotonic`. @@ -62,7 +62,7 @@ STATIC mp_obj_t time_monotonic(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic); -//| .. method:: sleep(seconds) +//| .. function:: sleep(seconds) //| //| Sleep for a given number of seconds. //| @@ -95,19 +95,20 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp return namedtuple_make_new(type, 9, tuple->items, NULL); } -//| .. class:: struct_time((tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)) +//| .. class:: struct_time(time_tuple) //| //| Structure used to capture a date and time. Note that it takes a tuple! //| -//| :param int tm_year: the year, 2017 for example -//| :param int tm_mon: the month, range [1, 12] -//| :param int tm_mday: the day of the month, range [1, 31] -//| :param int tm_hour: the hour, range [0, 23] -//| :param int tm_min: the minute, range [0, 59] -//| :param int tm_sec: the second, range [0, 61] -//| :param int tm_wday: the day of the week, range [0, 6], Monday is 0 -//| :param int tm_yday: the day of the year, range [1, 366], -1 indicates not known -//| :param int tm_isdst: 1 when in daylight savings, 0 when not, -1 if unknown. +//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info. +//| * the year, 2017 for example +//| * the month, range [1, 12] +//| * the day of the month, range [1, 31] +//| * the hour, range [0, 23] +//| * the minute, range [0, 59] +//| * the second, range [0, 61] +//| * the day of the week, range [0, 6], Monday is 0 +//| * the day of the year, range [1, 366], -1 indicates not known +//| * 1 when in daylight savings, 0 when not, -1 if unknown. //| const mp_obj_namedtuple_type_t struct_time_type_obj = { .base = { @@ -190,7 +191,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { mp_raise_RuntimeError(translate("RTC is not supported on this board")); } -//| .. method:: time() +//| .. function:: time() //| //| Return the current time in seconds since since Jan 1, 1970. //| @@ -206,7 +207,7 @@ STATIC mp_obj_t time_time(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); -//| .. method:: monotonic_ns() +//| .. function:: monotonic_ns() //| //| Return the time of the specified clock clk_id in nanoseconds. //| @@ -219,7 +220,7 @@ STATIC mp_obj_t time_monotonic_ns(void) { } MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); -//| .. method:: localtime([secs]) +//| .. function:: localtime([secs]) //| //| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in //| local time. If secs is not provided or None, the current time as returned @@ -245,7 +246,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); -//| .. method:: mktime(t) +//| .. function:: mktime(t) //| //| This is the inverse function of localtime(). Its argument is the //| struct_time or full 9-tuple (since the dst flag is needed; use -1 as the diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 3b26aca8c..78fceef41 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -88,6 +88,12 @@ STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_deinit); +STATIC void check_for_deinit(touchio_touchin_obj_t *self) { + if (common_hal_touchio_touchin_deinited(self)) { + raise_deinited_error(); + } +} + //| .. method:: __enter__() //| //| No-op used by Context Managers. @@ -114,7 +120,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t //| STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + check_for_deinit(self); return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self)); } MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value); @@ -133,7 +139,7 @@ const mp_obj_property_t touchio_touchin_value_obj = { //| STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self)); } @@ -158,7 +164,7 @@ const mp_obj_property_t touchio_touchin_raw_value_obj = { //| STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self)); } @@ -166,7 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - raise_error_if_deinited(common_hal_touchio_touchin_deinited(self)); + check_for_deinit(self); uint32_t new_threshold = mp_obj_get_int(threshold_obj); if (new_threshold < 0 || new_threshold > UINT16_MAX) { // I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536. diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c index df18237ac..0d699cd28 100644 --- a/shared-bindings/uheap/__init__.c +++ b/shared-bindings/uheap/__init__.c @@ -38,7 +38,7 @@ //| :synopsis: Heap size analysis //| -//| .. method:: info(object) +//| .. function:: info(object) //| //| Prints memory debugging info for the given object and returns the //| estimated size. diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c index c4391c132..08b772e41 100644 --- a/shared-bindings/ustack/__init__.c +++ b/shared-bindings/ustack/__init__.c @@ -39,7 +39,7 @@ //| #if MICROPY_MAX_STACK_USAGE -//| .. method:: max_stack_usage() +//| .. function:: max_stack_usage() //| //| Return the maximum excursion of the stack so far. //| @@ -50,7 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(max_stack_usage_obj, max_stack_usage); #endif // MICROPY_MAX_STACK_USAGE -//| .. method:: stack_size() +//| .. function:: stack_size() //| //| Return the size of the entire stack. //| Same as in micropython.mem_info(), but returns a value instead @@ -61,7 +61,7 @@ STATIC mp_obj_t stack_size(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(stack_size_obj, stack_size); -//| .. method:: stack_usage() +//| .. function:: stack_usage() //| //| Return how much stack is currently in use. //| Same as micropython.stack_use(); duplicated here for convenience. diff --git a/shared-bindings/util.c b/shared-bindings/util.c index 80a0bdaeb..c1ca01e0a 100644 --- a/shared-bindings/util.c +++ b/shared-bindings/util.c @@ -32,11 +32,9 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -// Check if pin is None. If so, deinit() has already been called on the object, so complain. -void raise_error_if_deinited(bool deinited) { - if (deinited) { - mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object.")); - } +// If so, deinit() has already been called on the object, so complain. +void raise_deinited_error(void) { + mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object.")); } diff --git a/shared-bindings/util.h b/shared-bindings/util.h index b26ed7e93..33454f10e 100644 --- a/shared-bindings/util.h +++ b/shared-bindings/util.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H #define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H -void raise_error_if_deinited(bool deinited); +void raise_deinited_error(void); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 878095b2a..ac89cc691 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -138,7 +138,7 @@ const mp_obj_property_t wiznet5k_dhcp_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| .. method:: ifconfig(...) +//| .. method:: ifconfig(params=None) //| //| Called without parameters, returns a tuple of //| (ip_address, subnet_mask, gateway_address, dns_server) diff --git a/shared-module/audioio/WaveFile.h b/shared-module/audioio/WaveFile.h index 75a46c03b..2cee2b1d2 100644 --- a/shared-module/audioio/WaveFile.h +++ b/shared-module/audioio/WaveFile.h @@ -44,7 +44,7 @@ typedef struct { uint32_t bytes_remaining; uint8_t channel_count; - uint16_t sample_rate; + uint32_t sample_rate; uint32_t len; pyb_file_obj_t* file; diff --git a/shared-module/bleio/Address.h b/shared-module/bleio/Address.h index f0998c163..65f493c16 100644 --- a/shared-module/bleio/Address.h +++ b/shared-module/bleio/Address.h @@ -27,14 +27,12 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H #define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H -#include "shared-bindings/bleio/AddressType.h" - -#define BLEIO_ADDRESS_BYTES 6 +#define NUM_BLEIO_ADDRESS_BYTES 6 typedef struct { mp_obj_base_t base; - bleio_address_type_t type; - uint8_t value[BLEIO_ADDRESS_BYTES]; + uint8_t type; + uint8_t bytes[NUM_BLEIO_ADDRESS_BYTES]; } bleio_address_obj_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/bleio/ScanEntry.h index 2f01669e2..6ae7334a8 100644 --- a/shared-module/bleio/ScanEntry.h +++ b/shared-module/bleio/ScanEntry.h @@ -31,9 +31,9 @@ typedef struct { mp_obj_base_t base; - bleio_address_obj_t address; bool connectable; int8_t rssi; + bleio_address_obj_t address; mp_obj_t data; } bleio_scanentry_obj_t; diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index ac4de2fe5..be8502bc0 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -103,7 +103,7 @@ void reset_board_busses(void) { #endif #if BOARD_SPI bool display_using_spi = false; - #ifdef CIRCUITPY_DISPLAYIO + #if CIRCUITPY_DISPLAYIO for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].fourwire_bus.bus == spi_singleton) { display_using_spi = true; diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 3b1613974..0ae88300a 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -107,28 +107,26 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, supervisor_start_terminal(width, height); - // Set the group after initialization otherwise we may send pixels while we delay in - // initialization. - self->refresh = true; - self->current_group = &circuitpython_splash; - self->width = width; self->height = height; rotation = rotation % 360; - self->mirror_x = false; - self->mirror_y = false; - self->transpose_xy = false; + 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->mirror_x = true; - self->mirror_y = true; + self->transform.mirror_x = true; + self->transform.mirror_y = true; } } else { - self->transpose_xy = true; - if (rotation == 90) { - self->mirror_y = true; + self->transform.transpose_xy = true; + if (rotation == 270) { + self->transform.mirror_y = true; } else { - self->mirror_x = true; + self->transform.mirror_x = true; } } @@ -148,13 +146,52 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, } } } + + 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 + // initialization. + common_hal_displayio_display_show(self, &circuitpython_splash); } void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { if (root_group == NULL) { root_group = &circuitpython_splash; } + if (root_group == self->current_group) { + return; + } + displayio_group_update_transform(root_group, &self->transform); self->current_group = root_group; + self->full_refresh = true; common_hal_displayio_display_refresh_soon(self); } @@ -162,6 +199,15 @@ void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) { self->refresh = true; } +const displayio_area_t* displayio_display_get_refresh_areas(displayio_display_obj_t *self) { + if (self->full_refresh) { + 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. @@ -224,7 +270,6 @@ void displayio_display_end_transaction(displayio_display_obj_t* self) { } void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { - self->send(self->bus, true, &self->set_column_command, 1); bool isCommand = self->data_as_commands; if (self->single_byte_bounds) { @@ -255,13 +300,16 @@ void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint1 } } -bool displayio_display_frame_queued(displayio_display_obj_t* self) { - // Refresh at ~30 fps. - return (ticks_ms - self->last_refresh) > 32; +void displayio_display_start_refresh(displayio_display_obj_t* self) { + self->last_refresh = ticks_ms; } -bool displayio_display_refresh_queued(displayio_display_obj_t* self) { - return self->refresh || (self->current_group != NULL && displayio_group_needs_refresh(self->current_group)); +bool displayio_display_frame_queued(displayio_display_obj_t* self) { + if (self->current_group == NULL) { + return false; + } + // Refresh at ~60 fps. + return (ticks_ms - self->last_refresh) > 16; } void displayio_display_finish_refresh(displayio_display_obj_t* self) { @@ -269,11 +317,12 @@ void displayio_display_finish_refresh(displayio_display_obj_t* self) { displayio_group_finish_refresh(self->current_group); } self->refresh = false; + self->full_refresh = false; self->last_refresh = ticks_ms; } -void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) { - self->send(self->bus, false, (uint8_t*) pixels, length * 4); +void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length) { + self->send(self->bus, false, pixels, length); } void displayio_display_update_backlight(displayio_display_obj_t* self) { @@ -298,3 +347,11 @@ void release_display(displayio_display_obj_t* self) { common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); } } + +bool displayio_display_fill_area(displayio_display_obj_t *self, displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { + return displayio_group_fill_area(self->current_group, area, mask, buffer); +} + +bool displayio_display_clip_area(displayio_display_obj_t *self, const displayio_area_t* area, displayio_area_t* clipped) { + return displayio_area_compute_overlap(&self->area, area, clipped); +} diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h index 52f98a252..fa8902ced 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -31,6 +31,8 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/pulseio/PWMOut.h" +#include "shared-module/displayio/area.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); @@ -38,19 +40,8 @@ typedef void (*display_bus_end_transaction)(mp_obj_t bus); typedef struct { mp_obj_base_t base; mp_obj_t bus; - uint16_t width; - uint16_t height; - uint16_t color_depth; - uint8_t set_column_command; - uint8_t set_row_command; - uint8_t write_ram_command; displayio_group_t *current_group; - bool refresh; uint64_t last_refresh; - int16_t colstart; - int16_t rowstart; - bool single_byte_bounds; - bool data_as_commands; display_bus_begin_transaction begin_transaction; display_bus_send send; display_bus_end_transaction end_transaction; @@ -59,14 +50,29 @@ typedef struct { pulseio_pwmout_obj_t backlight_pwm; }; uint64_t last_backlight_refresh; - bool auto_brightness:1; - bool updating_backlight:1; - bool mirror_x; - bool mirror_y; - bool transpose_xy; + displayio_buffer_transform_t transform; + displayio_area_t area; + uint16_t width; + uint16_t height; + uint16_t color_depth; + int16_t colstart; + int16_t rowstart; + uint8_t set_column_command; + uint8_t set_row_command; + uint8_t write_ram_command; + bool refresh; + bool single_byte_bounds; + bool data_as_commands; + bool auto_brightness; + bool updating_backlight; + bool full_refresh; // New group means we need to refresh the whole display. } displayio_display_obj_t; +void displayio_display_start_refresh(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); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 40f112bf1..15060e87b 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -38,9 +38,85 @@ uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) { return self->scale; } +bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) { + bool first = true; + for (size_t i = 0; i < self->size; i++) { + mp_obj_t layer = self->children[i].native; + displayio_area_t layer_area; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) { + continue; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (!displayio_group_get_previous_area(layer, &layer_area)) { + continue; + } + } + if (first) { + displayio_area_copy(&layer_area, area); + first = false; + } else { + displayio_area_expand(area, &layer_area); + } + } + if (self->item_removed) { + if (first) { + displayio_area_copy(&self->dirty_area, area); + first = false; + } else { + displayio_area_expand(area, &self->dirty_area); + } + } + return !first; +} + +static void _update_child_transforms(displayio_group_t* self) { + if (!self->in_group) { + return; + } + for (size_t i = 0; i < self->size; i++) { + mp_obj_t layer = self->children[i].native; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_update_transform(layer, &self->absolute_transform); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_update_transform(layer, &self->absolute_transform); + } + } +} + +void displayio_group_update_transform(displayio_group_t *self, + const displayio_buffer_transform_t* parent_transform) { + self->in_group = parent_transform != NULL; + if (self->in_group) { + int16_t x = self->x; + int16_t y = self->y; + if (parent_transform->transpose_xy) { + x = y; + y = self->x; + } + self->absolute_transform.x = parent_transform->x + parent_transform->dx * x; + self->absolute_transform.y = parent_transform->y + parent_transform->dy * y; + self->absolute_transform.dx = parent_transform->dx * self->scale; + self->absolute_transform.dy = parent_transform->dy * self->scale; + self->absolute_transform.transpose_xy = parent_transform->transpose_xy; + self->absolute_transform.mirror_x = parent_transform->mirror_x; + self->absolute_transform.mirror_y = parent_transform->mirror_y; + + self->absolute_transform.scale = parent_transform->scale * self->scale; + } + _update_child_transforms(self); +} + void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale) { - self->needs_refresh = self->scale != scale; + if (self->scale == scale) { + return; + } + uint8_t parent_scale = self->absolute_transform.scale / self->scale; + self->absolute_transform.dx = self->absolute_transform.dx / self->scale * scale; + self->absolute_transform.dy = self->absolute_transform.dy / self->scale * scale; + self->absolute_transform.scale = parent_scale * scale; self->scale = scale; + _update_child_transforms(self); } mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) { @@ -48,8 +124,19 @@ mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self) { } void common_hal_displayio_group_set_x(displayio_group_t* self, mp_int_t x) { - self->needs_refresh = self->x != x; + if (self->x == x) { + return; + } + if (self->absolute_transform.transpose_xy) { + int16_t dy = self->absolute_transform.dy / self->scale; + self->absolute_transform.y += dy * (x - self->x); + } else { + int16_t dx = self->absolute_transform.dx / self->scale; + self->absolute_transform.x += dx * (x - self->x); + } + self->x = x; + _update_child_transforms(self); } mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) { @@ -57,21 +144,75 @@ mp_int_t common_hal_displayio_group_get_y(displayio_group_t* self) { } void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) { - self->needs_refresh = self->y != y; + if (self->y == y) { + return; + } + if (self->absolute_transform.transpose_xy) { + int8_t dx = self->absolute_transform.dx / self->scale; + self->absolute_transform.x += dx * (y - self->y); + } else { + int8_t dy = self->absolute_transform.dy / self->scale; + self->absolute_transform.y += dy * (y - self->y); + } self->y = y; + _update_child_transforms(self); } -void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) { - if (self->size == self->max_size) { - mp_raise_RuntimeError(translate("Group full")); - } +static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) { mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); if (native_layer == MP_OBJ_NULL) { native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); + } + displayio_tilegrid_t* tilegrid = native_layer; + if (tilegrid->in_group) { + mp_raise_ValueError(translate("Layer already in a group.")); + } else { + tilegrid->in_group = true; + } + displayio_tilegrid_update_transform(tilegrid, &self->absolute_transform); + } else { + displayio_group_t* group = native_layer; + if (group->in_group) { + mp_raise_ValueError(translate("Layer already in a group.")); + } else { + group->in_group = true; + } + displayio_group_update_transform(group, &self->absolute_transform); } - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); + return native_layer; +} + +static void _remove_layer(displayio_group_t* self, size_t index) { + mp_obj_t layer = self->children[index].native; + displayio_area_t layer_area; + bool rendered_last_frame = false; + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_t* tilegrid = layer; + rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area); + displayio_tilegrid_update_transform(tilegrid, NULL); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_t* group = layer; + rendered_last_frame = displayio_group_get_previous_area(group, &layer_area); + displayio_group_update_transform(group, NULL); + } + if (!rendered_last_frame) { + return; + } + if (!self->item_removed) { + displayio_area_copy(&layer_area, &self->dirty_area); + } else { + displayio_area_expand(&self->dirty_area, &layer_area); } + self->item_removed = true; +} + +void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) { + if (self->size == self->max_size) { + mp_raise_RuntimeError(translate("Group full")); + } + mp_obj_t native_layer = _add_layer(self, layer); // Shift everything right. for (size_t i = self->size; i > index; i--) { self->children[i] = self->children[i - 1]; @@ -79,19 +220,19 @@ void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp self->children[index].native = native_layer; self->children[index].original = layer; self->size++; - self->needs_refresh = true; } mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) { self->size--; mp_obj_t item = self->children[index].original; + _remove_layer(self, index); + // Shift everything left. for (size_t i = index; i < self->size; i++) { self->children[i] = self->children[i + 1]; } self->children[self->size].native = NULL; self->children[self->size].original = NULL; - self->needs_refresh = true; return item; } @@ -113,16 +254,10 @@ mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) { } void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) { - mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); - } - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass.")); - } + mp_obj_t native_layer = _add_layer(self, layer); + _remove_layer(self, index); self->children[index].native = native_layer; self->children[index].original = layer; - self->needs_refresh = true; } void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) { @@ -130,65 +265,58 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* self->y = y; self->children = child_array; self->max_size = max_size; - self->needs_refresh = false; + self->item_removed = false; self->scale = scale; + self->in_group = false; } -bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, uint16_t* pixel) { - x -= self->x; - y -= self->y; - // When we are scaled we need to substract all but one to ensure -scale to 0 divide down to -1. - // Normally -scale to scale both divide down to 0 because 0 is unsigned. - if (x < 0) { - x -= self->scale - 1; - } - if (y < 0) { - y -= self->scale - 1; - } - x /= self->scale; - y /= self->scale; +bool displayio_group_fill_area(displayio_group_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) { + // Track if any of the layers finishes filling in the given area. We can ignore any remaining + // layers at that point. + bool full_coverage = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { - if (displayio_tilegrid_get_pixel(layer, x, y, pixel)) { - return true; + if (displayio_tilegrid_fill_area(layer, area, mask, buffer)) { + full_coverage = true; + break; } } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { - if (displayio_group_get_pixel(layer, x, y, pixel)) { - return true; + if (displayio_group_fill_area(layer, area, mask, buffer)) { + full_coverage = true; + break; } } } - return false; + return full_coverage; } -bool displayio_group_needs_refresh(displayio_group_t *self) { - if (self->needs_refresh) { - return true; - } +void displayio_group_finish_refresh(displayio_group_t *self) { + self->item_removed = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { - if (displayio_tilegrid_needs_refresh(layer)) { - return true; - } + displayio_tilegrid_finish_refresh(layer); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { - if (displayio_group_needs_refresh(layer)) { - return true; - } + displayio_group_finish_refresh(layer); } } - return false; } -void displayio_group_finish_refresh(displayio_group_t *self) { - self->needs_refresh = false; +displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail) { + if (self->item_removed) { + self->dirty_area.next = tail; + tail = &self->dirty_area; + } + for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { - displayio_tilegrid_finish_refresh(layer); + tail = displayio_tilegrid_get_refresh_areas(layer, tail); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { - displayio_group_finish_refresh(layer); + tail = displayio_group_get_refresh_areas(layer, tail); } } + + return tail; } diff --git a/shared-module/displayio/Group.h b/shared-module/displayio/Group.h index 7826b9e66..7ce19a4cd 100644 --- a/shared-module/displayio/Group.h +++ b/shared-module/displayio/Group.h @@ -31,6 +31,7 @@ #include <stdint.h> #include "py/obj.h" +#include "shared-module/displayio/area.h" typedef struct { mp_obj_t native; @@ -39,18 +40,23 @@ typedef struct { typedef struct { mp_obj_base_t base; + displayio_group_child_t* children; int16_t x; int16_t y; uint16_t scale; uint16_t size; uint16_t max_size; - displayio_group_child_t* children; - bool needs_refresh; + bool item_removed; + bool in_group; + displayio_buffer_transform_t absolute_transform; + displayio_area_t dirty_area; // Catch all for changed area } displayio_group_t; void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y); -bool displayio_group_get_pixel(displayio_group_t *group, int16_t x, int16_t y, uint16_t *pixel); -bool displayio_group_needs_refresh(displayio_group_t *self); +bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area); +bool displayio_group_fill_area(displayio_group_t *group, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer); +void displayio_group_update_transform(displayio_group_t *group, const displayio_buffer_transform_t* parent_transform); void displayio_group_finish_refresh(displayio_group_t *self); +displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, displayio_area_t* tail); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_GROUP_H diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index e810be875..8dc6e766b 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -53,7 +53,11 @@ void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t uint32_t packed = r5 << 11 | g6 << 5 | b5; // swap bytes packed = __builtin_bswap16(packed); - self->colors[palette_index / 2] = masked | packed << shift; + uint32_t final_color = masked | packed << shift; + if (self->colors[palette_index / 2] == final_color) { + return; + } + self->colors[palette_index / 2] = final_color; self->needs_refresh = true; } diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 3212dfe8b..97b704c40 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -56,31 +56,123 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->bitmap_width_in_tiles = bitmap_width_in_tiles; self->width_in_tiles = width; self->height_in_tiles = height; - self->total_width = width * tile_width; - self->total_height = height * tile_height; + self->x = x; + self->y = y; + self->pixel_width = width * tile_width; + self->pixel_height = height * tile_height; self->tile_width = tile_width; self->tile_height = tile_height; self->bitmap = bitmap; self->pixel_shader = pixel_shader; - self->x = x; - self->y = y; + self->in_group = false; + self->first_draw = true; + self->flip_x = false; + self->flip_y = false; + self->transpose_xy = false; } +bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) { + if (self->first_draw) { + return false; + } + displayio_area_copy(&self->previous_area, area); + return true; +} + +void _update_current_x(displayio_tilegrid_t *self) { + int16_t width; + if (self->transpose_xy) { + width = self->pixel_height; + } else { + width = self->pixel_width; + } + if (self->absolute_transform->transpose_xy) { + self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->x; + self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + width); + if (self->current_area.y2 < self->current_area.y1) { + int16_t temp = self->current_area.y2; + self->current_area.y2 = self->current_area.y1; + self->current_area.y1 = temp; + } + } else { + self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->x; + self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + width); + if (self->current_area.x2 < self->current_area.x1) { + int16_t temp = self->current_area.x2; + self->current_area.x2 = self->current_area.x1; + self->current_area.x1 = temp; + } + } +} + +void _update_current_y(displayio_tilegrid_t *self) { + int16_t height; + if (self->transpose_xy) { + height = self->pixel_width; + } else { + height = self->pixel_height; + } + if (self->absolute_transform->transpose_xy) { + self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->y; + self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + height); + if (self->current_area.x2 < self->current_area.x1) { + int16_t temp = self->current_area.x2; + self->current_area.x2 = self->current_area.x1; + self->current_area.x1 = temp; + } + } else { + self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->y; + self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + height); + if (self->current_area.y2 < self->current_area.y1) { + int16_t temp = self->current_area.y2; + self->current_area.y2 = self->current_area.y1; + self->current_area.y1 = temp; + } + } +} + +void displayio_tilegrid_update_transform(displayio_tilegrid_t *self, + const displayio_buffer_transform_t* absolute_transform) { + self->in_group = absolute_transform != NULL; + self->absolute_transform = absolute_transform; + if (absolute_transform != NULL) { + self->moved = !self->first_draw; + + _update_current_x(self); + _update_current_y(self); + } else { + self->first_draw = true; + } +} mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self) { return self->x; } void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x) { - self->needs_refresh = self->x != x; + if (self->x == x) { + return; + } + + self->moved = !self->first_draw; + self->x = x; + if (self->absolute_transform != NULL) { + _update_current_x(self); + } } mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self) { return self->y; } void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y) { - self->needs_refresh = self->y != y; + if (self->y == y) { + return; + } + self->moved = !self->first_draw; self->y = y; + if (self->absolute_transform != NULL) { + _update_current_y(self); + } } mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self) { @@ -89,10 +181,9 @@ mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *se void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader) { self->pixel_shader = pixel_shader; - self->needs_refresh = true; + self->full_change = true; } - uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self) { return self->width_in_tiles; } @@ -121,21 +212,78 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t return; } tiles[y * self->width_in_tiles + x] = tile_index; - self->needs_refresh = true; + displayio_area_t temp_area; + displayio_area_t* tile_area; + if (!self->partial_change) { + tile_area = &self->dirty_area; + } else { + tile_area = &temp_area; + } + tile_area->x1 = x * self->tile_width; + tile_area->x2 = tile_area->x1 + self->tile_width; + tile_area->y1 = y * self->tile_height; + tile_area->y2 = tile_area->y1 + self->tile_height; + if (self->partial_change) { + displayio_area_expand(&self->dirty_area, &temp_area); + } + + self->partial_change = true; +} + +bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self) { + return self->flip_x; +} + +void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x) { + if (self->flip_x == flip_x) { + return; + } + self->flip_x = flip_x; + self->full_change = true; +} + +bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self) { + return self->flip_y; +} + +void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y) { + if (self->flip_y == flip_y) { + return; + } + self->flip_y = flip_y; + self->full_change = true; } +bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self) { + return self->transpose_xy; +} + +void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy) { + if (self->transpose_xy == transpose_xy) { + return; + } + self->transpose_xy = transpose_xy; + + // Square TileGrids do not change dimensions when transposed. + if (self->pixel_width == self->pixel_height) { + self->full_change = true; + return; + } + + _update_current_x(self); + _update_current_y(self); + + self->moved = true; +} void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { self->top_left_x = x; self->top_left_y = y; + self->full_change = true; } -bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t* pixel) { - x -= self->x; - y -= self->y; - if (y < 0 || y >= self->total_height || x >= self->total_width || x < 0) { - return false; - } +bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { + // If no tiles are present we have no impact. uint8_t* tiles = self->tiles; if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; @@ -143,46 +291,143 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t if (tiles == NULL) { return false; } - uint16_t tile_location = ((y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (x / self->tile_width + self->top_left_x) % self->width_in_tiles; - uint8_t tile = tiles[tile_location]; - uint16_t tile_x = tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + x % self->tile_width; - uint16_t tile_y = tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + y % self->tile_height; - uint32_t value = 0; - if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { - value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { - value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { - value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y); + displayio_area_t overlap; + if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) { + return false; } - if (self->pixel_shader == mp_const_none) { - *pixel = value; - return true; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_get_color(self->pixel_shader, value, pixel)) { - return true; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) { - return true; + int16_t x_stride = 1; + int16_t y_stride = displayio_area_width(area); + + bool flip_x = self->flip_x; + bool flip_y = self->flip_y; + if (self->transpose_xy != self->absolute_transform->transpose_xy) { + bool temp_flip = flip_x; + flip_x = flip_y; + flip_y = temp_flip; } - return false; -} + // How many pixels are outside of our area between us and the start of the row. + uint16_t start = 0; + if ((self->absolute_transform->dx < 0) != flip_x) { + start += (area->x2 - area->x1 - 1) * x_stride; + x_stride *= -1; + } + if ((self->absolute_transform->dy < 0) != flip_y) { + start += (area->y2 - area->y1 - 1) * y_stride; + y_stride *= -1; + } -bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) { - if (self->needs_refresh) { - return true; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { - return displayio_palette_needs_refresh(self->pixel_shader); - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { - return displayio_colorconverter_needs_refresh(self->pixel_shader); + // Track if this layer finishes filling in the given area. We can ignore any remaining + // layers at that point. + bool full_coverage = displayio_area_equal(area, &overlap); + + // TODO(tannewt): Skip coverage tracking if all pixels outside the overlap have already been + // set and our palette is all opaque. + + // TODO(tannewt): Check to see if the pixel_shader has any transparency. If it doesn't then we + // can either return full coverage or bulk update the mask. + displayio_area_t transformed; + displayio_area_transform_within(flip_x != (self->absolute_transform->dx < 0), flip_y != (self->absolute_transform->dy < 0), self->transpose_xy != self->absolute_transform->transpose_xy, + &overlap, + &self->current_area, + &transformed); + + int16_t start_x = (transformed.x1 - self->current_area.x1); + int16_t end_x = (transformed.x2 - self->current_area.x1); + int16_t start_y = (transformed.y1 - self->current_area.y1); + int16_t end_y = (transformed.y2 - self->current_area.y1); + + int16_t y_shift = 0; + int16_t x_shift = 0; + if ((self->absolute_transform->dx < 0) != flip_x) { + x_shift = area->x2 - overlap.x2; + } else { + x_shift = overlap.x1 - area->x1; + } + if ((self->absolute_transform->dy < 0) != flip_y) { + y_shift = area->y2 - overlap.y2; + } else { + y_shift = overlap.y1 - area->y1; } - return false; + // This untransposes x and y so it aligns with bitmap rows. + if (self->transpose_xy != self->absolute_transform->transpose_xy) { + int16_t temp_stride = x_stride; + x_stride = y_stride; + y_stride = temp_stride; + int16_t temp_shift = x_shift; + x_shift = y_shift; + y_shift = temp_shift; + } + + for (int16_t y = start_y; y < end_y; y++) { + int16_t row_start = start + (y - start_y + y_shift) * y_stride; + int16_t local_y = y / self->absolute_transform->scale; + for (int16_t x = start_x; x < end_x; x++) { + // Compute the destination pixel in the buffer and mask based on the transformations. + int16_t offset = row_start + (x - start_x + x_shift) * x_stride; + + // This is super useful for debugging out range accesses. Uncomment to use. + // if (offset < 0 || offset >= (int32_t) displayio_area_size(area)) { + // asm("bkpt"); + // } + + // Check the mask first to see if the pixel has already been set. + if ((mask[offset / 32] & (1 << (offset % 32))) != 0) { + continue; + } + int16_t local_x = x / self->absolute_transform->scale; + uint16_t tile_location = ((local_y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles; + uint8_t tile = tiles[tile_location]; + uint16_t tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width; + uint16_t tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height; + + uint32_t value = 0; + // We always want to read bitmap pixels by row first and then transpose into the destination + // buffer because most bitmaps are row associated. + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + value = common_hal_displayio_bitmap_get_pixel(self->bitmap, tile_x, tile_y); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + value = common_hal_displayio_shape_get_pixel(self->bitmap, tile_x, tile_y); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y); + } + + uint16_t* pixel = ((uint16_t*) buffer) + offset; + if (self->pixel_shader == mp_const_none) { + *pixel = value; + return true; + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { + if (!displayio_palette_get_color(self->pixel_shader, value, pixel)) { + // A pixel is transparent so we haven't fully covered the area ourselves. + full_coverage = false; + } else { + mask[offset / 32] |= 1 << (offset % 32); + } + } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { + if (!common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) { + // A pixel is transparent so we haven't fully covered the area ourselves. + full_coverage = false; + } else { + mask[offset / 32] |= 1 << (offset % 32); + } + } + } + } + return full_coverage; } void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { - self->needs_refresh = false; + if (self->moved || self->first_draw) { + displayio_area_copy(&self->current_area, &self->previous_area); + } + + self->moved = false; + self->full_change = false; + self->partial_change = false; + self->first_draw = false; if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { displayio_palette_finish_refresh(self->pixel_shader); } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { @@ -191,3 +436,58 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { // TODO(tannewt): We could double buffer changes to position and move them over here. // That way they won't change during a refresh and tear. } + +displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail) { + if (self->moved && !self->first_draw) { + displayio_area_union(&self->previous_area, &self->current_area, &self->dirty_area); + if (displayio_area_size(&self->dirty_area) <= 2 * self->pixel_width * self->pixel_height) { + self->dirty_area.next = tail; + return &self->dirty_area; + } + self->previous_area.next = tail; + self->current_area.next = &self->previous_area; + return &self->current_area; + } + + // We must recheck if our sources require a refresh because needs_refresh may or may not have + // been called. + self->full_change = self->full_change || + (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && + displayio_palette_needs_refresh(self->pixel_shader)) || + (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && + displayio_colorconverter_needs_refresh(self->pixel_shader)); + if (self->full_change || self->first_draw) { + self->current_area.next = tail; + return &self->current_area; + } + + if (self->partial_change) { + if (self->absolute_transform->transpose_xy) { + int16_t x1 = self->dirty_area.x1; + self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y1); + self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x1); + int16_t x2 = self->dirty_area.x2; + self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + self->dirty_area.y2); + self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + x2); + } else { + self->dirty_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x1); + self->dirty_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y1); + self->dirty_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + self->dirty_area.x2); + self->dirty_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + self->dirty_area.y2); + } + if (self->dirty_area.y2 < self->dirty_area.y1) { + int16_t temp = self->dirty_area.y2; + self->dirty_area.y2 = self->dirty_area.y1; + self->dirty_area.y1 = temp; + } + if (self->dirty_area.x2 < self->dirty_area.x1) { + int16_t temp = self->dirty_area.x2; + self->dirty_area.x2 = self->dirty_area.x1; + self->dirty_area.x1 = temp; + } + + self->dirty_area.next = tail; + return &self->dirty_area; + } + return tail; +} diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index 59645553d..4d97eccc2 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -31,29 +31,52 @@ #include <stdint.h> #include "py/obj.h" +#include "shared-module/displayio/area.h" typedef struct { mp_obj_base_t base; mp_obj_t bitmap; mp_obj_t pixel_shader; - uint16_t x; - uint16_t y; + int16_t x; + int16_t y; + uint16_t pixel_width; + uint16_t pixel_height; uint16_t bitmap_width_in_tiles; uint16_t width_in_tiles; uint16_t height_in_tiles; - uint16_t total_width; - uint16_t total_height; uint16_t tile_width; uint16_t tile_height; uint16_t top_left_x; uint16_t top_left_y; uint8_t* tiles; - bool needs_refresh; + const displayio_buffer_transform_t* absolute_transform; + displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched. + displayio_area_t previous_area; // Stored as an absolute area. + displayio_area_t current_area; // Stored as an absolute area so it applies across frames. + bool partial_change; + bool full_change; + bool first_draw; + bool moved; bool inline_tiles; + bool in_group; + bool flip_x; + bool flip_y; + bool transpose_xy; } displayio_tilegrid_t; -bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t y, uint16_t *pixel); -bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self); +// Updating the screen is a three stage process. + +// The first stage is used to determine i +displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail); + +// Area is always in absolute screen coordinates. Update transform is used to inform TileGrids how +// they relate to it. +bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer); +void displayio_tilegrid_update_transform(displayio_tilegrid_t *group, const displayio_buffer_transform_t* parent_transform); + +// Fills in area with the maximum bounds of all related pixels in the last rendered frame. Returns +// false if the tilegrid wasn't rendered in the last frame. +bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area); void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_TILEGRID_H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 156640440..b6709e0eb 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,8 +1,10 @@ #include <string.h> + #include "shared-module/displayio/__init__.h" #include "lib/utils/interrupt_char.h" +#include "py/gc.h" #include "py/reload.h" #include "py/runtime.h" #include "shared-bindings/board/__init__.h" @@ -10,6 +12,7 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-module/displayio/area.h" #include "supervisor/shared/autoreload.h" #include "supervisor/shared/display.h" #include "supervisor/memory.h" @@ -17,14 +20,83 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -static inline void swap(uint16_t* a, uint16_t* b) { - uint16_t temp = *a; - *a = *b; - *b = temp; +bool refresh_area(displayio_display_obj_t* display, const displayio_area_t* area) { + uint16_t buffer_size = 512; + + 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_clip_area(display, area, &clipped)) { + return true; + } + uint16_t subrectangles = 1; + uint16_t rows_per_buffer = displayio_area_height(&clipped); + if (displayio_area_size(area) > buffer_size) { + rows_per_buffer = buffer_size / displayio_area_width(&clipped); + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + buffer_size = rows_per_buffer * displayio_area_width(&clipped); + } + uint32_t buffer[buffer_size / 2]; + 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.x1, subrectangle.y1, + subrectangle.x2, subrectangle.y2); + displayio_display_end_transaction(display); + + uint32_t mask[(buffer_size / 32) + 1]; + for (uint16_t k = 0; k < (buffer_size / 32) + 1; k++) { + mask[k] = 0x00000000; + } + + bool full_coverage = displayio_display_fill_area(display, &subrectangle, mask, buffer); + if (!full_coverage) { + uint32_t index = 0; + uint32_t current_mask = 0; + for (int16_t y = subrectangle.y1; y < subrectangle.y2; y++) { + for (int16_t x = subrectangle.x1; x < subrectangle.x2; x++) { + if (index % 32 == 0) { + current_mask = mask[index / 32]; + } + if ((current_mask & (1 << (index % 32))) == 0) { + ((uint16_t*) buffer)[index] = 0x0000; + } + index++; + } + } + } + + 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, displayio_area_size(&subrectangle) * sizeof(uint16_t)); + 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; +uint32_t frame_count = 0; void displayio_refresh_displays(void) { if (mp_hal_is_interrupted()) { @@ -55,105 +127,19 @@ void displayio_refresh_displays(void) { // Too soon. Try next display. continue; } - if (displayio_display_refresh_queued(display)) { - // We compute the pixels. r and c are row and column to match the display memory - // structure. x and y match location within the groups. - uint16_t c0 = 0; - uint16_t r0 = 0; - uint16_t c1 = display->width; - uint16_t r1 = display->height; - if (display->transpose_xy) { - swap(&c1, &r1); - } - - if (!displayio_display_begin_transaction(display)) { - // Can't acquire display bus; skip updating this display. Try next display. - continue; - } - displayio_display_set_region_to_update(display, c0, r0, c1, r1); - displayio_display_end_transaction(display); - - uint16_t x0 = 0; - uint16_t x1 = display->width - 1; - uint16_t startx = 0; - int8_t dx = 1; - if (display->mirror_x) { - dx = -1; - startx = x1; - } - uint16_t y0 = 0; - uint16_t y1 = display->height - 1; - uint16_t starty = 0; - int8_t dy = 1; - if (display->mirror_y) { - dy = -1; - starty = y1; - } - - bool transpose = false; - if (display->transpose_xy) { - transpose = true; - int8_t temp_dx = dx; - dx = dy; - dy = temp_dx; - - swap(&starty, &startx); - swap(&x0, &y0); - swap(&x1, &y1); - } - - size_t index = 0; - uint16_t buffer_size = 256; - uint32_t buffer[buffer_size / 2]; - bool skip_this_display = false; - - for (uint16_t y = starty; y0 <= y && y <= y1; y += dy) { - for (uint16_t x = startx; x0 <= x && x <= x1; x += dx) { - uint16_t* pixel = &(((uint16_t*)buffer)[index]); - *pixel = 0; - - if (display->current_group != NULL) { - if (transpose) { - displayio_group_get_pixel(display->current_group, y, x, pixel); - } else { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } - } - - index += 1; - // The buffer is full, send it. - if (index >= buffer_size) { - if (!displayio_display_begin_transaction(display)) { - // Can't acquire display bus; skip the rest of the data. Try next display. - index = 0; - skip_this_display = true; - break; - } - displayio_display_send_pixels(display, buffer, buffer_size / 2); - displayio_display_end_transaction(display); - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. - usb_background(); - index = 0; - } - } - } - - if (skip_this_display) { - // Go on to next display. - continue; - } - // Send the remaining data. - if (index) { - if (!displayio_display_begin_transaction(display)) { - // Can't get display bus. Skip the rest of the data. Try next display. - continue; - } - displayio_display_send_pixels(display, buffer, index * 2); - } - displayio_display_end_transaction(display); + 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. @@ -181,7 +167,6 @@ void common_hal_displayio_release_displays(void) { } void reset_displays(void) { - #if CIRCUITPY_DISPLAYIO // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) { @@ -218,5 +203,151 @@ void reset_displays(void) { display->auto_brightness = true; common_hal_displayio_display_show(display, &circuitpython_splash); } - #endif +} + +void displayio_gc_collect(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + + // Alternatively, we could use gc_collect_root over the whole object, + // but this is more precise, and is the only field that needs marking. + gc_collect_ptr(displays[i].display.current_group); + + } +} + +void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition) { + if (addition->x1 < original->x1) { + original->x1 = addition->x1; + } + if (addition->y1 < original->y1) { + original->y1 = addition->y1; + } + if (addition->x2 > original->x2) { + original->x2 = addition->x2; + } + if (addition->y2 > original->y2) { + original->y2 = addition->y2; + } +} + +void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst) { + dst->x1 = src->x1; + dst->y1 = src->y1; + dst->x2 = src->x2; + dst->y2 = src->y2; +} + +void displayio_area_scale(displayio_area_t* area, uint16_t scale) { + area->x1 *= scale; + area->y1 *= scale; + area->x2 *= scale; + area->y2 *= scale; +} + +void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy) { + area->x1 += dx; + area->y1 += dy; + area->x2 += dx; + area->y2 += dy; +} + +bool displayio_area_compute_overlap(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* overlap) { + overlap->x1 = a->x1; + if (b->x1 > overlap->x1) { + overlap->x1 = b->x1; + } + overlap->x2 = a->x2; + if (b->x2 < overlap->x2) { + overlap->x2 = b->x2; + } + if (overlap->x1 >= overlap->x2) { + return false; + } + overlap->y1 = a->y1; + if (b->y1 > overlap->y1) { + overlap->y1 = b->y1; + } + overlap->y2 = a->y2; + if (b->y2 < overlap->y2) { + overlap->y2 = b->y2; + } + if (overlap->y1 >= overlap->y2) { + return false; + } + return true; +} + +void displayio_area_union(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* u) { + u->x1 = a->x1; + if (b->x1 < u->x1) { + u->x1 = b->x1; + } + u->x2 = a->x2; + if (b->x2 > u->x2) { + u->x2 = b->x2; + } + + u->y1 = a->y1; + if (b->y1 < u->y1) { + u->y1 = b->y1; + } + u->y2 = a->y2; + if (b->y2 > u->y2) { + u->y2 = b->y2; + } +} + +uint16_t displayio_area_width(const displayio_area_t* area) { + return area->x2 - area->x1; +} + +uint16_t displayio_area_height(const displayio_area_t* area) { + return area->y2 - area->y1; +} + +uint32_t displayio_area_size(const displayio_area_t* area) { + return displayio_area_width(area) * displayio_area_height(area); +} + +bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b) { + return a->x1 == b->x1 && + a->y1 == b->y1 && + a->x2 == b->x2 && + a->y2 == b->y2; +} + +// Original and whole must be in the same coordinate space. +void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, + const displayio_area_t* original, + const displayio_area_t* whole, + displayio_area_t* transformed) { + if (mirror_x) { + transformed->x1 = whole->x1 + (whole->x2 - original->x2); + transformed->x2 = whole->x2 - (original->x1 - whole->x1); + } else { + transformed->x1 = original->x1; + transformed->x2 = original->x2; + } + if (mirror_y) { + transformed->y1 = whole->y1 + (whole->y2 - original->y2); + transformed->y2 = whole->y2 - (original->y1 - whole->y1); + } else { + transformed->y1 = original->y1; + transformed->y2 = original->y2; + } + if (transpose_xy) { + int16_t y1 = transformed->y1; + int16_t y2 = transformed->y2; + transformed->y1 = whole->y1 + (transformed->x1 - whole->x1); + transformed->y2 = whole->y1 + (transformed->x2 - whole->x1); + transformed->x2 = whole->x1 + (y2 - whole->y1); + transformed->x1 = whole->x1 + (y1 - whole->y1); + } } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 5b56ed55c..18c1a4f4a 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H +#ifndef 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/FourWire.h" @@ -46,5 +46,6 @@ extern displayio_group_t circuitpython_splash; void displayio_refresh_displays(void); void reset_displays(void); +void displayio_gc_collect(void); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H diff --git a/shared-module/displayio/area.h b/shared-module/displayio/area.h new file mode 100644 index 000000000..ec7c389b4 --- /dev/null +++ b/shared-module/displayio/area.h @@ -0,0 +1,73 @@ +/* + * 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_MODULE_DISPLAYIO_AREA_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H + +// Implementations are in __init__.c +typedef struct _displayio_area_t displayio_area_t; + +struct _displayio_area_t { + int16_t x1; + int16_t y1; + int16_t x2; // Second point is exclusive. + int16_t y2; + const displayio_area_t* next; // Next area in the linked list. +}; + +typedef struct { + uint16_t x; + uint16_t y; + int8_t dx; + int8_t dy; + uint8_t scale; + uint16_t width; + uint16_t height; + bool mirror_x; + bool mirror_y; + bool transpose_xy; +} displayio_buffer_transform_t; + +void displayio_area_union(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* u); +void displayio_area_expand(displayio_area_t* original, const displayio_area_t* addition); +void displayio_area_copy(const displayio_area_t* src, displayio_area_t* dst); +void displayio_area_scale(displayio_area_t* area, uint16_t scale); +void displayio_area_shift(displayio_area_t* area, int16_t dx, int16_t dy); +bool displayio_area_compute_overlap(const displayio_area_t* a, + const displayio_area_t* b, + displayio_area_t* overlap); +uint16_t displayio_area_width(const displayio_area_t* area); +uint16_t displayio_area_height(const displayio_area_t* area); +uint32_t displayio_area_size(const displayio_area_t* area); +bool displayio_area_equal(const displayio_area_t* a, const displayio_area_t* b); +void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, + const displayio_area_t* original, + const displayio_area_t* whole, + displayio_area_t* transformed); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 0b3fbe178..c3afb3e00 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -50,6 +50,10 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { } width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale); uint16_t height_in_tiles = height_px / (grid->tile_height * scale); + uint16_t remaining_pixels = height_px % (grid->tile_height * scale); + if (remaining_pixels > 0) { + height_in_tiles += 1; + } circuitpython_splash.scale = scale; uint16_t total_tiles = width_in_tiles * height_in_tiles; @@ -67,11 +71,13 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { if (tiles == NULL) { return; } - + if (remaining_pixels > 0) { + grid->y -= (grid->tile_height - remaining_pixels); + } grid->width_in_tiles = width_in_tiles; grid->height_in_tiles = height_in_tiles; - grid->total_width = width_in_tiles * grid->tile_width; - grid->total_height = height_in_tiles * grid->tile_height; + grid->pixel_width = width_in_tiles * grid->tile_width; + grid->pixel_height = height_in_tiles * grid->tile_height; grid->tiles = tiles; supervisor_terminal.cursor_x = 0; @@ -159,18 +165,22 @@ displayio_tilegrid_t blinka_sprite = { .pixel_shader = &blinka_palette, .x = 0, .y = 0, + .pixel_width = 16, + .pixel_height = 16, .bitmap_width_in_tiles = 1, .width_in_tiles = 1, .height_in_tiles = 1, - .total_width = 16, - .total_height = 16, .tile_width = 16, .tile_height = 16, .top_left_x = 16, .top_left_y = 16, .tiles = 0, - .needs_refresh = false, - .inline_tiles = true + .partial_change = false, + .full_change = false, + .first_draw = true, + .moved = false, + .inline_tiles = true, + .in_group = true }; displayio_group_child_t splash_children[2] = { @@ -186,5 +196,5 @@ displayio_group_t circuitpython_splash = { .size = 2, .max_size = 2, .children = splash_children, - .needs_refresh = true + .item_removed = false }; diff --git a/tools/build_release_files.py b/tools/build_release_files.py index 872302a4f..e29b098c7 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -1,3 +1,5 @@ +#! /usr/bin/env python3 + import os import sys import subprocess @@ -6,7 +8,7 @@ import build_board_info as build_info import time for port in build_info.SUPPORTED_PORTS: - result = subprocess.run("rm -rf ../ports/{}/build*".format(port), shell=True) + result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) ROSIE_SETUPS = ["rosie-ci"] rosie_ok = {} @@ -37,7 +39,25 @@ for board in build_boards: bin_directory = "../bin/{board}/{language}".format(board=board, language=language) os.makedirs(bin_directory, exist_ok=True) start_time = time.monotonic() - make_result = subprocess.run("make -C ../ports/" + board_info["port"] + " TRANSLATION=" + language + " BOARD=" + board, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + # Normally different language builds are all done based on the same set of compiled sources. + # But sometimes a particular language needs to be built from scratch, if, for instance, + # CFLAGS_INLINE_LIMIT is set for a particular language to make it fit. + clean_build_check_result = subprocess.run( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} check-release-needs-clean-build | fgrep 'RELEASE_NEEDS_CLEAN_BUILD = 1'".format( + port = board_info["port"], language=language, board=board), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + clean_build = clean_build_check_result.returncode == 0 + + build_dir = "build-{board}".format(board=board) + if clean_build: + build_dir += "-{language}".format(language=language) + + make_result = subprocess.run( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build}".format( + port = board_info["port"], language=language, board=board, build=build_dir), + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + build_duration = time.monotonic() - start_time success = "\033[32msucceeded\033[0m" if make_result.returncode != 0: @@ -47,11 +67,14 @@ for board in build_boards: other_output = "" for extension in board_info["extensions"]: - temp_filename = "../ports/{port}/build-{board}/firmware.{extension}".format(port=board_info["port"], board=board, extension=extension) + temp_filename = "../ports/{port}/{build}/firmware.{extension}".format( + port=board_info["port"], build=build_dir, extension=extension) for alias in board_info["aliases"] + [board]: - bin_directory = "../bin/{alias}/{language}".format(alias=alias, language=language) + bin_directory = "../bin/{alias}/{language}".format( + alias=alias, language=language) os.makedirs(bin_directory, exist_ok=True) - final_filename = "adafruit-circuitpython-{alias}-{language}-{version}.{extension}".format(alias=alias, language=language, version=version, extension=extension) + final_filename = "adafruit-circuitpython-{alias}-{language}-{version}.{extension}".format( + alias=alias, language=language, version=version, extension=extension) final_filename = os.path.join(bin_directory, final_filename) try: shutil.copyfile(temp_filename, final_filename) @@ -62,7 +85,9 @@ for board in build_boards: if travis: print('travis_fold:start:adafruit-bins-{}-{}\\r'.format(language, board)) - print("Build {} for {} took {:.2f}s and {}".format(board, language, build_duration, success)) + print("Build {board} for {language}{clean_build} took {build_duration:.2f}s and {success}".format( + board=board, language=language, clean_build=(" (clean_build)" if clean_build else ""), + build_duration=build_duration, success=success)) if make_result.returncode != 0: print(make_result.stdout.decode("utf-8")) print(other_output) diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index ebea9dccc..7b28c3105 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -122,16 +122,20 @@ displayio_tilegrid_t supervisor_terminal_text_grid = {{ .pixel_shader = &supervisor_terminal_color, .x = 16, .y = 0, + .pixel_width = {1}, + .pixel_height = {2}, .bitmap_width_in_tiles = {0}, .width_in_tiles = 1, .height_in_tiles = 1, - .total_width = {1}, - .total_height = {2}, .tile_width = {1}, .tile_height = {2}, .tiles = NULL, - .needs_refresh = false, - .inline_tiles = false + .partial_change = false, + .full_change = false, + .first_draw = true, + .moved = false, + .inline_tiles = false, + .in_group = true }}; """.format(len(all_characters), tile_x, tile_y)) diff --git a/tools/git-checkout-latest-tag.sh b/tools/git-checkout-latest-tag.sh new file mode 100755 index 000000000..f6242a946 --- /dev/null +++ b/tools/git-checkout-latest-tag.sh @@ -0,0 +1,3 @@ +#!/bin/bash +git fetch --tags +git checkout $(git describe --tags `git rev-list --tags --max-count=1`) |
