diff --git a/.gitattributes b/.gitattributes index 5ebde95f07..c077807abe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18,6 +18,7 @@ *.deb binary *.zip binary *.pdf binary +*.wav binary # These should also not be modified by git. tests/basics/string_cr_conversion.py -text diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 34e0b08217..a7d0f8a981 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -208,6 +208,7 @@ jobs: - "datum_imu" - "datum_light" - "datum_weather" + - "dynalora_usb" - "dynossat_edu_eps" - "dynossat_edu_obc" - "electronut_labs_blip" @@ -280,6 +281,9 @@ jobs: - "pewpew10" - "pewpew_m4" - "picoplanet" + - "pimoroni_keybow2040" + - "pimoroni_picosystem" + - "pimoroni_tiny2040" - "pirkey_m0" - "pitaya_go" - "pyb_nano_v2" @@ -295,6 +299,7 @@ jobs: - "pyruler" - "qtpy_m0" - "qtpy_m0_haxpress" + - "qtpy_rp2040" - "raspberry_pi_pico" - "raytac_mdbt50q-db-40" - "robohatmm1_m4" @@ -451,6 +456,7 @@ jobs: - "targett_module_clip_wrover" - "unexpectedmaker_feathers2" - "unexpectedmaker_feathers2_prerelease" + - "unexpectedmaker_tinys2" steps: - name: Set up Python 3.8 diff --git a/conf.py b/conf.py index 0a163e7d3c..0454ff5ec5 100644 --- a/conf.py +++ b/conf.py @@ -178,6 +178,7 @@ exclude_patterns = ["**/build*", "ports/cxd56/spresense-exported-sdk", "ports/esp32s2/certificates", "ports/esp32s2/esp-idf", + "ports/esp32s2/.idf_tools", "ports/esp32s2/peripherals", "ports/litex/hw", "ports/minimal", diff --git a/docs/design_guide.rst b/docs/design_guide.rst index 7a8c76b507..3317570347 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -165,6 +165,24 @@ use what. Here is more info on properties from `Python `_. +Exceptions and asserts +-------------------------------------------------------------------------------- + +Raise an appropriate `Exception `_, +along with a useful message, whenever a critical test or other condition fails. + +Example:: + + if not 0 <= pin <= 7: + raise ValueError("Pin number must be 0-7.") + +If memory is constrained and a more compact method is needed, use `assert` +instead. + +Example:: + + assert 0 <= pin <= 7, "Pin number must be 0-7." + Design for compatibility with CPython -------------------------------------------------------------------------------- diff --git a/extmod/crypto-algorithms/sha256.c b/extmod/crypto-algorithms/sha256.c index 276611cfd5..9b5e45d23d 100644 --- a/extmod/crypto-algorithms/sha256.c +++ b/extmod/crypto-algorithms/sha256.c @@ -14,6 +14,7 @@ /*************************** HEADER FILES ***************************/ #include +#include #include "sha256.h" /****************************** MACROS ******************************/ diff --git a/extmod/ulab b/extmod/ulab index 743d86487c..2ecad9586d 160000 --- a/extmod/ulab +++ b/extmod/ulab @@ -1 +1 @@ -Subproject commit 743d86487c83e42024ed508ed50499ad0a527d5d +Subproject commit 2ecad9586d088ee66f1b208ff2204906eba9e987 diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index 1e3312ab1c..0cfa671b0c 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit 1e3312ab1cba0b1d3bb1f559c52acfdc1a6d57b8 +Subproject commit 0cfa671b0c38386ba4da59119d61d399faa9b358 diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index dd7cc167c5..5fee6e0c38 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit dd7cc167c528a94a9feed81f9c52b5d372f68258 +Subproject commit 5fee6e0c3878110844bc51e16063eeae7d94c457 diff --git a/frozen/pew-pewpew-standalone-10.x b/frozen/pew-pewpew-standalone-10.x index a14da2e1ce..88b8be84b5 160000 --- a/frozen/pew-pewpew-standalone-10.x +++ b/frozen/pew-pewpew-standalone-10.x @@ -1 +1 @@ -Subproject commit a14da2e1ced1010a0da65f758199ff08eedd0bd5 +Subproject commit 88b8be84b5dce7660f58c02a63263f1d2ff0709f diff --git a/locale/ID.po b/locale/ID.po index c592acf9f7..e1aed308ac 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -368,6 +368,7 @@ msgstr "Semua timer untuk pin ini sedang digunakan" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Semua timer sedang digunakan" @@ -1112,6 +1113,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1467,9 +1473,14 @@ msgstr "Tidak ada DAC (Digital Analog Converter) di dalam chip" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "tidak ada channel DMA ditemukan" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1680,6 +1691,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Sampel berlebihan harus kelipatan 8." @@ -1756,6 +1772,10 @@ msgstr "" "ideal. Jika ini tidak dapat dihindari, berikan allow_inefficient=True ke " "konstruktor" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Tambahkan module apapun pada filesystem\n" @@ -1996,6 +2016,14 @@ msgstr "Memisahkan dengan menggunakan sub-captures" msgid "Stack size must be at least 256" msgstr "Ukuran stack minimal harus 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Aliran tidak menemukan metode readinto() atau write()." @@ -2167,6 +2195,7 @@ msgstr "Nilai UUID bukan str, int atau byte buffer" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" @@ -3359,6 +3388,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "modul tidak ditemukan" @@ -3674,6 +3707,10 @@ msgstr "Muncul dari PulseIn yang kosong" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4131,6 +4168,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 529bc6d52c..f9ef4ad13c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -363,6 +363,7 @@ msgstr "" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "" @@ -1091,6 +1092,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1446,9 +1452,14 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1653,6 +1664,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1724,6 +1740,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1963,6 +1983,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "" @@ -2126,6 +2154,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3308,6 +3337,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" @@ -3622,6 +3655,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4078,6 +4115,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 870b82c732..c6d537fcce 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -366,6 +366,7 @@ msgstr "" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "" @@ -1094,6 +1095,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1449,9 +1455,14 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1656,6 +1667,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1727,6 +1743,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1966,6 +1986,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "" @@ -2129,6 +2157,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3311,6 +3340,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" @@ -3625,6 +3658,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4081,6 +4118,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 11e743aa5c..dfb60ca4e4 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -368,6 +368,7 @@ msgstr "Alle timer für diesen Pin werden bereits benutzt" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Alle timer werden benutzt" @@ -1112,6 +1113,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "Initialisierung aufgrund von Speichermangel fehlgeschlagen" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1469,9 +1475,14 @@ msgstr "Kein DAC im Chip vorhanden" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Kein DMA Kanal gefunden" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1682,6 +1693,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample muss ein Vielfaches von 8 sein." @@ -1756,6 +1772,10 @@ msgstr "" "Bytes verbraucht. Wenn dies nicht vermieden werden kann, übergeben Sie " "allow_inefficient = True an den Konstruktor" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "und alle Module im Dateisystem \n" @@ -1995,6 +2015,14 @@ msgstr "Splitting mit sub-captures" msgid "Stack size must be at least 256" msgstr "Die Stackgröße sollte mindestens 256 sein" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Stream fehlt readinto() oder write() Methode." @@ -2172,6 +2200,7 @@ msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren" @@ -3389,6 +3418,10 @@ msgstr "Speicherzuordnung fehlgeschlagen, Zuweisung von %u Bytes" msgid "memory allocation failed, heap is locked" msgstr "Speicherzuweisung fehlgeschlagen, der Heap ist gesperrt" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "Modul nicht gefunden" @@ -3707,6 +3740,10 @@ msgstr "pop von einem leeren PulseIn" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "pow() drittes Argument darf nicht 0 sein" @@ -4170,6 +4207,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/el.po b/locale/el.po index fe281db4e4..b088a7645f 100644 --- a/locale/el.po +++ b/locale/el.po @@ -363,6 +363,7 @@ msgstr "" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "" @@ -1091,6 +1092,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1446,9 +1452,14 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1653,6 +1664,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1724,6 +1740,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1963,6 +1983,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "" @@ -2126,6 +2154,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3308,6 +3337,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" @@ -3622,6 +3655,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4078,6 +4115,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/es.po b/locale/es.po index 0a02df3b56..c5e199719b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,27 +8,31 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2020-12-30 22:25+0000\n" -"Last-Translator: Hugo Dahl \n" +"PO-Revision-Date: 2021-02-21 22:27+0000\n" +"Last-Translator: Jose David M \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.4.1-dev\n" +"X-Generator: Weblate 4.5\n" #: main.c msgid "" "\n" "Code done running.\n" msgstr "" +"\n" +"El código terminó de ejecutar.\n" #: main.c msgid "" "\n" "Code stopped by auto-reload.\n" msgstr "" +"\n" +"El código fue detenido por el auto-reiniciado.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -50,7 +54,7 @@ msgstr " Archivo \"%q\", línea %d" #: py/builtinhelp.c msgid " is of type %q\n" -msgstr "" +msgstr " es de tipo %q\n" #: main.c msgid " output:\n" @@ -66,6 +70,8 @@ msgstr "%%c requiere int o char" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d pines de dirección, %d pines rgb y %d tiles indican una altura de %d, y " +"no de %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" @@ -126,7 +132,7 @@ msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" -msgstr "" +msgstr "%s error 0x%x" #: py/argcheck.c msgid "'%q' argument required" @@ -292,7 +298,7 @@ msgstr "pow() con 3 argumentos no soportado" #: shared-module/msgpack/__init__.c msgid "64 bit types" -msgstr "" +msgstr "tipos de 64 bit" #: ports/atmel-samd/common-hal/countio/Counter.c #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c @@ -346,7 +352,7 @@ msgstr "Todos los canales de eventos estan siendo usados" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "All state machines in use" -msgstr "" +msgstr "Todas las máquinas de estado en uso" #: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c msgid "All sync event channels in use" @@ -370,6 +376,7 @@ msgstr "Todos los timers para este pin están siendo utilizados" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Todos los timers en uso" @@ -567,7 +574,7 @@ msgstr "Los bloques CBC deben ser múltiplos de 16 bytes" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "CRC or checksum was invalid" -msgstr "" +msgstr "CRC o suma de comprobación inválida" #: py/objtype.c msgid "Call super().__init__() before accessing native object." @@ -575,15 +582,17 @@ msgstr "Llame a super().__ init __() antes de acceder al objeto nativo." #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." -msgstr "" +msgstr "Solo puede alertar en RTC IO de deep sleep." #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Solo puede alertar en un pin low mientras los otros alertan en high viniendo " +"de deep sleep." #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on two low pins from deep sleep." -msgstr "" +msgstr "Solo puede alerta en dos low pines viniendo de deep sleep." #: ports/nrf/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -622,7 +631,7 @@ msgstr "No se puede tener ambos canales en el mismo pin" #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "" +msgstr "No puede hacer pull en un pin de entrada sola." #: shared-module/bitbangio/SPI.c msgid "Cannot read without MISO pin." @@ -644,7 +653,7 @@ msgstr "No se puede reiniciar a bootloader porque no hay bootloader presente." #: ports/esp32s2/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "" +msgstr "No se pueden definir opciones para enchufe" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -673,7 +682,7 @@ msgstr "No puede variar la frecuencia en un temporizador que ya está en uso" #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." -msgstr "" +msgstr "No puede despertar en pin edge, solo en nivel." #: shared-module/bitbangio/SPI.c msgid "Cannot write without MOSI pin." @@ -830,7 +839,7 @@ msgstr "El pin Data 0 debe estar alineado a bytes" #: ports/esp32s2/common-hal/displayio/ParallelBus.c msgid "Data 0 pin must be byte aligned." -msgstr "" +msgstr "El pin de datos 0 debe ser alineado a byte." #: shared-module/audiocore/WaveFile.c msgid "Data chunk must follow fmt chunk" @@ -888,7 +897,7 @@ msgstr "Error en regex" #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "Error: Failure to bind" -msgstr "" +msgstr "Error: fallo al vincular" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c py/enum.c #: shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c @@ -926,7 +935,7 @@ msgstr "Se esperaba una dirección" #: shared-bindings/alarm/__init__.c msgid "Expected an alarm" -msgstr "" +msgstr "Un objecto alarm era esperado" #: shared-module/_pixelbuf/PixelBuf.c #, c-format @@ -1017,7 +1026,7 @@ msgstr "Filtros muy complejos" #: ports/esp32s2/common-hal/dualbank/__init__.c msgid "Firmware image is invalid" -msgstr "" +msgstr "La imagen de firmware es inválida" #: ports/cxd56/common-hal/camera/Camera.c msgid "Format not supported" @@ -1040,7 +1049,7 @@ msgstr "La función requiere lock" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Generic Failure" -msgstr "" +msgstr "Fallo Genérico" #: shared-bindings/displayio/Display.c #: shared-bindings/displayio/EPaperDisplay.c @@ -1076,7 +1085,7 @@ msgstr "I2C Error de inicio" #: ports/raspberrypi/common-hal/busio/I2C.c msgid "I2C peripheral in use" -msgstr "" +msgstr "Dispositivo I2C en uso" #: shared-bindings/audiobusio/I2SOut.c msgid "I2SOut not available" @@ -1084,7 +1093,7 @@ msgstr "I2SOut no disponible" #: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" +msgstr "IOs 0, 2 y 4 no soportan pullup interno durante sleep" #: shared-bindings/aesio/aes.c #, c-format @@ -1105,12 +1114,19 @@ msgstr "Tamaño incorrecto del buffer" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Init program size invalid" -msgstr "" +msgstr "Tamaño del programa Init invalido" #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "Initialization failed due to lack of memory" msgstr "Inicializacion fallida por falta de memoria" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" +"La longitud del buffer de entrada(%d) debe ser un múltiplo del conteo de la " +"tira (%d)" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "La entrada está durando mucho tiempo" @@ -1122,27 +1138,27 @@ msgstr "error Input/output" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d jumps on pin" -msgstr "" +msgstr "La instruction %d salta en pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" -msgstr "" +msgstr "La instruccion %d mueve mas bits que la cuenta del pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts out more bits than pin count" -msgstr "" +msgstr "La instruccion %d mueve mas bits que la cuenta del pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d uses extra pin" -msgstr "" +msgstr "La instrucción %d usa un pin extra" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d waits on input outside of count" -msgstr "" +msgstr "La instrucción %d espera una entrada fuera del conteo" #: ports/nrf/common-hal/_bleio/__init__.c msgid "Insufficient authentication" @@ -1201,7 +1217,7 @@ msgstr "Frecuencia PWM inválida" #: ports/esp32s2/common-hal/analogio/AnalogIn.c msgid "Invalid Pin" -msgstr "" +msgstr "Pin inválido" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #: py/moduerrno.c shared-module/rgbmatrix/RGBMatrix.c @@ -1317,15 +1333,15 @@ msgstr "'security_mode' no válido" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Invalid size" -msgstr "" +msgstr "Tamaño incorrecto" #: ports/esp32s2/common-hal/ssl/SSLContext.c msgid "Invalid socket for TLS" -msgstr "" +msgstr "socket invalido para TLS" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Invalid state" -msgstr "" +msgstr "Estado invalido" #: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice" @@ -1369,7 +1385,7 @@ msgstr "Length no deberia ser negativa" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "MAC address was invalid" -msgstr "" +msgstr "La dirección MAC es incorrecta" #: shared-module/bitbangio/SPI.c msgid "MISO pin init failed." @@ -1407,32 +1423,36 @@ msgstr "Falta el pin MISO o MOSI" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d reads pin(s)" -msgstr "" +msgstr "first-in-pin no encontrado. La instrucción %d lee el/los pin(es)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d shifts in from pin(s)" -msgstr "" +msgstr "first_in_pin no encontrado. La instrucción %d desplaza de los pin(es)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d waits based on pin" msgstr "" +"first_in_pin no encontrado. La instrucción %d espera basada en este pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_out_pin. Instruction %d shifts out to pin(s)" msgstr "" +"first_in_pin no encontrado. La instrucción %d mueve hacia afuera hacia el/" +"los pin(es)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_out_pin. Instruction %d writes pin(s)" -msgstr "" +msgstr "first_in_pin no encontrado. La instrucción %d escribe pin(es)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +"first_set_pin no encontrado. La instrucción %d configura el/los pin(es)" #: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." @@ -1466,13 +1486,18 @@ msgstr "El chip no tiene DAC" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "No se encontró el canal DMA" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "timer por establecedor de paso DMA no encontrado" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" -msgstr "" +msgstr "No hay dispositivo I2C en la dirección: %x" #: ports/esp32s2/common-hal/busio/SPI.c ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/stm/common-hal/busio/SPI.c @@ -1553,13 +1578,13 @@ msgstr "No hay una red con ese ssid" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No out in program" -msgstr "" +msgstr "No hay out en el programa" #: ports/atmel-samd/common-hal/busio/I2C.c ports/esp32s2/common-hal/busio/I2C.c #: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "" +msgstr "No se encontró pull up en SDA or SCL; verifique su cableado" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" @@ -1620,7 +1645,7 @@ msgstr "Solo mono de 8 ó 16 bit con " #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Only IN/OUT of up to 8 supported" -msgstr "" +msgstr "Solamente IN/OUT hasta 8 esta soportado" #: ports/esp32s2/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" @@ -1649,11 +1674,11 @@ msgstr "" #: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c msgid "Only one TouchAlarm can be set in deep sleep." -msgstr "" +msgstr "Solamente una TouchAlarm puede ser configurada durante deep sleep." #: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set." -msgstr "" +msgstr "Solamente una alarm.time puede ser configurada." #: shared-module/displayio/ColorConverter.c msgid "Only one color can be transparent at a time" @@ -1665,27 +1690,32 @@ msgstr "Solo se aceptan enteros crudos para ip" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Operation or feature not supported" -msgstr "" +msgstr "Operación no característica no soportada" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Operation timed out" -msgstr "" +msgstr "Tiempo de espera agotado" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Out of memory" -msgstr "" +msgstr "Memoria agotada" #: ports/esp32s2/common-hal/socketpool/SocketPool.c msgid "Out of sockets" msgstr "Se acabaron los enchufes" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "buffer de salida debe ser de por lo menos %d bytes" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "El sobremuestreo debe ser un múltiplo de 8." #: shared-bindings/audiobusio/PDMIn.c msgid "PDMIn not available" -msgstr "" +msgstr "PDMIn no esta disponible" #: shared-bindings/pwmio/PWMOut.c msgid "" @@ -1707,7 +1737,7 @@ msgstr "ParallelBus todavía no soportado" #: ports/esp32s2/common-hal/audiobusio/__init__.c msgid "Peripheral in use" -msgstr "" +msgstr "Periférico en uso" #: py/moduerrno.c msgid "Permission denied" @@ -1715,11 +1745,11 @@ msgstr "Permiso denegado" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Pin count must be at least 1" -msgstr "" +msgstr "El total de pines debe ser por lo menos 1" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Pin count too large" -msgstr "" +msgstr "Total de pines demasiado grande" #: ports/atmel-samd/common-hal/analogio/AnalogIn.c #: ports/cxd56/common-hal/analogio/AnalogIn.c @@ -1755,6 +1785,10 @@ msgstr "" "ideales. Si esto no se puede evitar, pase allow_inefficient=True al " "constructor" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "Los pines deben compartir la división PWM" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Además de cualquier módulo en el sistema de archivos\n" @@ -1789,30 +1823,33 @@ msgstr "El prefijo del buffer debe estar en el heap" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"Presiona cualquier tecla para entrar al REPL. Usa CTRL-D para recargar.\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" msgstr "" +"Pretendiendo ir a deep sleep hasta la alarma, CTRL-C or una escritura de " +"archivo\n" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does IN without loading ISR" -msgstr "" +msgstr "El programa hace un IN sin cargar ISR" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does OUT without loading OSR" -msgstr "" +msgstr "El programa hace OUT sin cargar OSR" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program must contain at least one 16-bit instruction." -msgstr "" +msgstr "El programa debe contener por lo menos una instrucción de 16 bits." #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program size invalid" -msgstr "" +msgstr "El tamaño del programa no es correcto" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program too large" -msgstr "" +msgstr "Programa demasiado grande" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1820,7 +1857,7 @@ msgstr "Pull no se usa cuando la dirección es output." #: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c msgid "RAISE mode is not implemented" -msgstr "" +msgstr "El modo RAISE no esta implementado" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1832,7 +1869,7 @@ msgstr "Error de inicialización de RNG" #: ports/nrf/common-hal/busio/UART.c msgid "RS485 Not yet supported on this device" -msgstr "" +msgstr "RS485 no esta soportado todavía en este dispositivo" #: ports/esp32s2/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1873,7 +1910,7 @@ msgstr "Objeto de solo-lectura" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Received response was invalid" -msgstr "" +msgstr "La respuesta recibida es invalida" #: shared-bindings/displayio/EPaperDisplay.c msgid "Refresh too soon" @@ -1889,7 +1926,7 @@ msgstr "El modo AES solicitado no es compatible" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Requested resource not found" -msgstr "" +msgstr "Recurso solicitado no encontrado" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "Right channel unsupported" @@ -1927,7 +1964,7 @@ msgstr "Error de reinicialización de SPI" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" -msgstr "" +msgstr "Periférico SPI en uso" #: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" @@ -1961,11 +1998,11 @@ msgstr "El contexto del lado del servidor no puede tener un hostname" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Set pin count must be between 1 and 5" -msgstr "" +msgstr "La suma de pines configurados debe estar entre 1 y 5" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Side set pin count must be between 1 and 5" -msgstr "" +msgstr "El conteo de pines de Side set debe estar entre 1 y 5" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" @@ -1998,6 +2035,14 @@ msgstr "Dividiendo con sub-capturas" msgid "Stack size must be at least 256" msgstr "El tamaño de la pila debe ser de al menos 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "Estéreo izquierdo debe estar en el canal PWM A" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "Estéreo derecho debe estar en el canal PWM B" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "A Stream le falta el método readinto() o write()." @@ -2008,7 +2053,7 @@ msgstr "Suministre al menos un pin UART" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" -msgstr "" +msgstr "Suministre monotonic_time o epoch_time" #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" @@ -2084,7 +2129,7 @@ msgstr "Ancho del Tile debe dividir exactamente el ancho de mapa de bits" #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." -msgstr "" +msgstr "Tiempo suministrado esta en el pasado." #: ports/nrf/common-hal/_bleio/Adapter.c #, c-format @@ -2147,7 +2192,7 @@ msgstr "Error de reinicialización de UART" #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART not yet supported" -msgstr "" +msgstr "UART no esta soportado todavia" #: ports/stm/common-hal/busio/UART.c msgid "UART write error" @@ -2175,6 +2220,7 @@ msgstr "UUID valor no es un str, int o byte buffer" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "No se pudieron asignar buffers para la conversión con signo" @@ -2206,7 +2252,7 @@ msgstr "Imposible escribir en nvm." #: shared-bindings/alarm/SleepMemory.c msgid "Unable to write to sleep_memory." -msgstr "" +msgstr "Imposible de escribir en sleep_memory." #: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" @@ -2220,7 +2266,7 @@ msgstr "Error no manejado de ESP TLS %d %d %x %d" #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" -msgstr "" +msgstr "Fallo desconocido %d" #: ports/nrf/common-hal/_bleio/__init__.c #, c-format @@ -2278,7 +2324,7 @@ msgstr "valor pull no soportado." #: ports/esp32s2/common-hal/dualbank/__init__.c msgid "Update Failed" -msgstr "" +msgstr "La actualización fallo" #: ports/nrf/common-hal/_bleio/Characteristic.c #: ports/nrf/common-hal/_bleio/Descriptor.c @@ -2292,7 +2338,7 @@ msgstr "Tamaño de valor > max_length" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "Version was invalid" -msgstr "" +msgstr "La versión era invalida" #: py/emitnative.c msgid "Viper functions don't currently support more than 4 arguments" @@ -2352,7 +2398,7 @@ msgstr "La clave de WiFi debe ser entre 8 y 63 caracteres" #: main.c msgid "Woken up by alarm.\n" -msgstr "" +msgstr "Despertado por la alarma.\n" #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Writes not supported on Characteristic" @@ -2499,7 +2545,7 @@ msgstr "la rama no está dentro del rango" #: extmod/ulab/code/ulab_create.c msgid "buffer is smaller than requested size" -msgstr "" +msgstr "El buffer es mas pequeño que el requerido" #: shared-bindings/audiocore/RawSample.c msgid "buffer must be a bytes-like object" @@ -2507,7 +2553,7 @@ msgstr "buffer debe de ser un objeto bytes-like" #: extmod/ulab/code/ulab_create.c msgid "buffer size must be a multiple of element size" -msgstr "" +msgstr "El tamaño del buffer debe ser un múltiplo del tamaño del elemento" #: shared-module/struct/__init__.c msgid "buffer size must match format" @@ -2721,7 +2767,7 @@ msgstr "circulo solo puede ser registrado con un pariente" #: shared-bindings/msgpack/ExtType.c msgid "code outside range 0~127" -msgstr "" +msgstr "código fuera del rango 0~127" #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" @@ -2797,7 +2843,7 @@ msgstr "los datos deben ser de igual tamaño" #: extmod/ulab/code/ndarray.c msgid "data type not understood" -msgstr "" +msgstr "tipo de dato no comprendido" #: py/parsenum.c msgid "decimal numbers not supported" @@ -2809,7 +2855,7 @@ msgstr "'except' por defecto deberia estar de último" #: shared-bindings/msgpack/__init__.c msgid "default is not a function" -msgstr "" +msgstr "default no es una función" #: shared-bindings/audiobusio/PDMIn.c msgid "" @@ -2869,7 +2915,7 @@ msgstr "end_x debe ser un int" #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" -msgstr "" +msgstr "epoch_time no esta soportado en esta tarjeta" #: ports/nrf/common-hal/busio/UART.c #, c-format @@ -2914,7 +2960,7 @@ msgstr "esperando la clave:valor para dict" #: shared-bindings/msgpack/__init__.c msgid "ext_hook is not a function" -msgstr "" +msgstr "ext_hook no es una función" #: py/argcheck.c msgid "extra keyword arguments given" @@ -3120,7 +3166,7 @@ msgstr "Formas de entrada y salida no son compactibles" #: extmod/ulab/code/ulab_create.c msgid "input argument must be an integer, a tuple, or a list" -msgstr "" +msgstr "argumento de entrada debe ser un entero, una tupla o una lista" #: extmod/ulab/code/fft/fft.c msgid "input array length must be power of 2" @@ -3246,7 +3292,7 @@ msgstr "sintaxis inválida para número" #: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "io must be rtc io" -msgstr "" +msgstr "io debe ser rtc io" #: py/objtype.c msgid "issubclass() arg 1 must be a class" @@ -3347,7 +3393,7 @@ msgstr "max_length debe ser 0-%d cuando fixed_length es %s" #: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c msgid "max_length must be >= 0" -msgstr "" +msgstr "max_length debe ser >= 0" #: extmod/ulab/code/ndarray.c msgid "maximum number of dimensions is 4" @@ -3367,7 +3413,7 @@ msgstr "maxiter debe ser > 0" #: extmod/ulab/code/numerical/numerical.c msgid "median argument must be an ndarray" -msgstr "" +msgstr "argumento median debe ser una matriz ndarray" #: py/runtime.c #, c-format @@ -3378,6 +3424,11 @@ msgstr "la asignación de memoria falló, asignando %u bytes" msgid "memory allocation failed, heap is locked" msgstr "la asignación de memoria falló, el heap está bloqueado" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" +"memoryview: la longitud no es un múltiplo del tamaño del elemento (itemsize)" + #: py/builtinimport.c msgid "module not found" msgstr "módulo no encontrado" @@ -3453,7 +3504,7 @@ msgstr "no se ha encontrado ningún enlace para nonlocal" #: shared-module/msgpack/__init__.c msgid "no default packer" -msgstr "" +msgstr "no hay empaquetador por defecto" #: py/builtinimport.c msgid "no module named '%q'" @@ -3496,11 +3547,11 @@ msgstr "" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "non-zero timeout must be > 0.01" -msgstr "" +msgstr "el tiempo de espera non-zero deber ser > 0.01" #: shared-bindings/_bleio/Adapter.c msgid "non-zero timeout must be >= interval" -msgstr "" +msgstr "el tiempo de espera non-zero debe ser >= intervalo" #: extmod/ulab/code/linalg/linalg.c msgid "norm is defined for 1D and 2D arrays" @@ -3525,7 +3576,7 @@ msgstr "el número de puntos debe ser al menos 2" #: py/builtinhelp.c msgid "object " -msgstr "" +msgstr "objecto " #: py/obj.c msgid "object '%q' is not a tuple or list" @@ -3581,11 +3632,11 @@ msgstr "offset es demasiado grande" #: shared-bindings/dualbank/__init__.c msgid "offset must be >= 0" -msgstr "" +msgstr "offset debe ser >= 0" #: extmod/ulab/code/ulab_create.c msgid "offset must be non-negative and no greater than buffer length" -msgstr "" +msgstr "offset debe ser non-negative y no mayo que la longitud del buffer" #: py/objstr.c py/objstrunicode.c msgid "offset out of bounds" @@ -3695,6 +3746,10 @@ msgstr "pop de un PulseIn vacío" msgid "pop from empty %q" msgstr "pop desde %q vacía" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "port debe ser be >= 0" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "el 3er argumento de pow() no puede ser 0" @@ -3731,11 +3786,11 @@ msgstr "presionando ambos botones al inicio.\n" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "pull_threshold must be between 1 and 32" -msgstr "" +msgstr "pull_threshold debe esta entre 1 y 32" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "push_threshold must be between 1 and 32" -msgstr "" +msgstr "push_threshold debe esta entre 1 y 32" #: extmod/modutimeq.c msgid "queue overflow" @@ -3814,7 +3869,7 @@ msgstr "forma tiene que ser una tupla" #: shared-module/msgpack/__init__.c msgid "short read" -msgstr "" +msgstr "lectura corta" #: py/objstr.c msgid "sign not allowed in string format specifier" @@ -3934,7 +3989,7 @@ msgstr "limite debe ser en el rango 0-65536" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "tile must be greater than zero" -msgstr "" +msgstr "tile debe sera mas grande que cero" #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" @@ -3953,7 +4008,7 @@ msgstr "el tiempo de espera debe ser 0.0-100.0 segundos" #: ports/nrf/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" -msgstr "" +msgstr "timeout debe ser < 655.35 segundos" #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "timeout must be >= 0.0" @@ -3981,7 +4036,7 @@ msgstr "demasiados argumentos provistos con el formato dado" #: extmod/ulab/code/ulab_create.c msgid "too many dimensions" -msgstr "" +msgstr "demasiadas dimensiones" #: extmod/ulab/code/ndarray.c msgid "too many indices" @@ -3994,7 +4049,7 @@ msgstr "demasiados valores para descomprimir (%d esperado)" #: extmod/ulab/code/approx/approx.c msgid "trapz is defined for 1D arrays" -msgstr "" +msgstr "trapz esta definido para matrices 1D" #: extmod/ulab/code/approx/approx.c msgid "trapz is defined for 1D arrays of equal length" @@ -4002,7 +4057,7 @@ msgstr "trapz está definido para arreglos 1D de igual tamaño" #: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "trigger level must be 0 or 1" -msgstr "" +msgstr "nivel de accionamiento debe ser 0 o 1" #: py/obj.c msgid "tuple/list has wrong length" @@ -4144,7 +4199,7 @@ msgstr "los vectores deben tener el mismo tamaño" #: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "wakeup conflict" -msgstr "" +msgstr "conflicto de wakeup" #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" @@ -4154,13 +4209,18 @@ msgstr "watchdog no inicializado" msgid "watchdog timeout must be greater than 0" msgstr "el tiempo de espera del perro guardián debe ser mayor a 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "ancho debe estar entre 2 y 8 (inclusivamente), no %d" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "el ancho debe ser mayor que cero" #: ports/esp32s2/common-hal/wifi/Radio.c msgid "wifi is not enabled" -msgstr "" +msgstr "wifi no esta habilitado" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4200,7 +4260,7 @@ msgstr "valor x fuera de límites" #: ports/esp32s2/common-hal/audiobusio/__init__.c msgid "xTaskCreate failed" -msgstr "" +msgstr "fallo en xTaskCreate" #: shared-bindings/displayio/Shape.c msgid "y should be an int" diff --git a/locale/fil.po b/locale/fil.po index 71d5ef8f1f..1eecc49dc9 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -366,6 +366,7 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Lahat ng timer ginagamit" @@ -1106,6 +1107,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1461,9 +1467,14 @@ msgstr "Walang DAC sa chip" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Walang DMA channel na mahanap" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1671,6 +1682,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample ay dapat multiple ng 8." @@ -1743,6 +1759,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Kasama ang kung ano pang modules na sa filesystem\n" @@ -1983,6 +2003,14 @@ msgstr "Binibiyak gamit ang sub-captures" msgid "Stack size must be at least 256" msgstr "Ang laki ng stack ay dapat na hindi bababa sa 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Stream kulang ng readinto() o write() method." @@ -2146,6 +2174,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Hindi ma-allocate ang buffers para sa naka-sign na conversion" @@ -3355,6 +3384,10 @@ msgstr "nabigo ang paglalaan ng memorya, paglalaan ng %u bytes" msgid "memory allocation failed, heap is locked" msgstr "abigo ang paglalaan ng memorya, ang heap ay naka-lock" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "module hindi nakita" @@ -3671,6 +3704,10 @@ msgstr "pop mula sa walang laman na PulseIn" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "pow() 3rd argument ay hindi maaring 0" @@ -4131,6 +4168,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 895c87f5ec..a53d8658e1 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-01-30 02:32+0000\n" -"Last-Translator: Antonin ENFRUN \n" +"PO-Revision-Date: 2021-02-21 22:27+0000\n" +"Last-Translator: Hugo Dahl \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.5-dev\n" +"X-Generator: Weblate 4.5\n" #: main.c msgid "" @@ -352,7 +352,7 @@ msgstr "Tous les canaux d'événements sont utilisés" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "All state machines in use" -msgstr "" +msgstr "Tous les automates finis sont utilisés" #: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c msgid "All sync event channels in use" @@ -374,6 +374,7 @@ msgstr "Tous les minuteurs pour cette broche sont utilisés" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Tous les minuteurs sont utilisés" @@ -656,7 +657,7 @@ msgstr "" #: ports/esp32s2/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "" +msgstr "Ne peut définir les options de socket" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -1093,7 +1094,7 @@ msgstr "Erreur d'initialisation I2C" #: ports/raspberrypi/common-hal/busio/I2C.c msgid "I2C peripheral in use" -msgstr "" +msgstr "périphérique I2C utilisé" #: shared-bindings/audiobusio/I2SOut.c msgid "I2SOut not available" @@ -1122,12 +1123,19 @@ msgstr "Taille de tampon incorrecte" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Init program size invalid" -msgstr "" +msgstr "Taille du programme d'initialisation non valide" #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "Initialization failed due to lack of memory" msgstr "Échec d'initialisation par manque de mémoire" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" +"La taille (%d) du tampon d'entrée doit être un multiple du nombre (%d) de " +"brins" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "L'entrée prend trop de temps" @@ -1139,27 +1147,31 @@ msgstr "Erreur d'entrée/sortie" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d jumps on pin" -msgstr "" +msgstr "Instruction %d saute sur la broche" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" msgstr "" +"Instruction %d décale vers l'intérieur de plus de bits que le nombre de " +"broches" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts out more bits than pin count" msgstr "" +"instruction %d décale vers l'extérieur de plus de bits que le nombre de " +"broches" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d uses extra pin" -msgstr "" +msgstr "instruction %d utilise des broches supplémentaires" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d waits on input outside of count" -msgstr "" +msgstr "instruction %d attend sur une entrée hors du compte" #: ports/nrf/common-hal/_bleio/__init__.c msgid "Insufficient authentication" @@ -1424,32 +1436,33 @@ msgstr "Broche MISO ou MOSI manquante" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d reads pin(s)" -msgstr "" +msgstr "first_in_pin manquant. Instruction %d lit une/des broche(s)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d shifts in from pin(s)" -msgstr "" +msgstr "first_in_pin manquant. Instruction %d est déplacée par la/les broche(s)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_in_pin. Instruction %d waits based on pin" -msgstr "" +msgstr "first_in_pin manquant. L'instruction %d attends dépends de la broche" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_out_pin. Instruction %d shifts out to pin(s)" msgstr "" +"first_out_pin manquant. Instruction %d est déplacée par la/les broche(s)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_out_pin. Instruction %d writes pin(s)" -msgstr "" +msgstr "first_out_pin manquant. Instruction %d écrit un/des broche(s)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Missing first_set_pin. Instruction %d sets pin(s)" -msgstr "" +msgstr "first_set_pin manquant. L'instruction %d règle la/les broche(s)" #: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." @@ -1483,9 +1496,14 @@ msgstr "Pas de DAC sur la puce" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Aucun canal DMA trouvé" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "Aucun minuteur de rythme DMA trouvé" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1570,13 +1588,13 @@ msgstr "Aucun réseau avec ce ssid" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No out in program" -msgstr "" +msgstr "Aucun out dans le programme" #: ports/atmel-samd/common-hal/busio/I2C.c ports/esp32s2/common-hal/busio/I2C.c #: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "" +msgstr "Aucun pull up trouvé sur SDA ou SCL; vérifiez votre cablage" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" @@ -1637,7 +1655,7 @@ msgstr "Uniquement 8 ou 16 bit mono avec " #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Only IN/OUT of up to 8 supported" -msgstr "" +msgstr "Seulement des IN/OUT jusqu'à 8 est supporté" #: ports/esp32s2/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" @@ -1696,6 +1714,11 @@ msgstr "Hors de mémoire" msgid "Out of sockets" msgstr "Plus de sockets" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "Tampon de sortie doit être au moins %d octets" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Le sur-échantillonage doit être un multiple de 8." @@ -1734,11 +1757,11 @@ msgstr "Permission refusée" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Pin count must be at least 1" -msgstr "" +msgstr "Nombre de broches doit être au moins 1" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Pin count too large" -msgstr "" +msgstr "Nombre de broches trop élevé" #: ports/atmel-samd/common-hal/analogio/AnalogIn.c #: ports/cxd56/common-hal/analogio/AnalogIn.c @@ -1774,6 +1797,10 @@ msgstr "" "octets idéal. Si cela ne peut pas être évité, transmettez allow_inefficient " "= True au constructeur" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "Les broches doivent partager la tranche PWM" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Ainsi que tout autres modules présents sur le système de fichiers\n" @@ -1818,23 +1845,23 @@ msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does IN without loading ISR" -msgstr "" +msgstr "Le programme fait des entrées sans charger d'ISR" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does OUT without loading OSR" -msgstr "" +msgstr "Le programme fait des sorties sans charger d'OSR" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program must contain at least one 16-bit instruction." -msgstr "" +msgstr "Le programme doit contenir au moins une instruction de 16 bits." #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program size invalid" -msgstr "" +msgstr "Taille du programme invalide" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program too large" -msgstr "" +msgstr "Programme trop grand" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1842,7 +1869,7 @@ msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." #: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c msgid "RAISE mode is not implemented" -msgstr "" +msgstr "Mode RAISE n'est pas implémenté" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1854,7 +1881,7 @@ msgstr "Erreur d'initialisation du RNG (RNG Init)" #: ports/nrf/common-hal/busio/UART.c msgid "RS485 Not yet supported on this device" -msgstr "" +msgstr "RS485 n'est pas encore supporté sur cet appareil" #: ports/esp32s2/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1949,7 +1976,7 @@ msgstr "Erreur de réinitialisation SPI" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" -msgstr "" +msgstr "Périphérique SPI utilisé" #: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" @@ -1983,11 +2010,11 @@ msgstr "Un contexte niveau serveur ne peut avoir de hostname" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Set pin count must be between 1 and 5" -msgstr "" +msgstr "Nombre de broches configurées doit être entre 1 et 5" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Side set pin count must be between 1 and 5" -msgstr "" +msgstr "Nombre de broches Side configurées doit être entre 1 et 5" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" @@ -2020,6 +2047,14 @@ msgstr "Fractionnement avec des sous-captures" msgid "Stack size must be at least 256" msgstr "La pile doit être au moins de 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "Canal stéréo gauche doit être sur le canal PWM A" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "Canal stéréo droit doit être sur le canal PWM B" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Il manque une méthode readinto() ou write() au flux." @@ -2167,7 +2202,7 @@ msgstr "Erreur de réinitialisation UART" #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART not yet supported" -msgstr "" +msgstr "UART n'est pas encore supporté" #: ports/stm/common-hal/busio/UART.c msgid "UART write error" @@ -2198,6 +2233,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Impossible d'allouer des tampons pour une conversion signée" @@ -3413,6 +3449,10 @@ msgstr "l'allocation de mémoire a échoué en allouant %u octets" msgid "memory allocation failed, heap is locked" msgstr "l'allocation de mémoire a échoué, le tas est vérrouillé" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "memoryview: length n'est pas un multiple de itemsize" + #: py/builtinimport.c msgid "module not found" msgstr "module introuvable" @@ -3732,6 +3772,10 @@ msgstr "'pop' d'une entrée PulseIn vide" msgid "pop from empty %q" msgstr "pop sur %q vide" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "port doit être >= 0" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "le 3e argument de pow() ne peut être 0" @@ -3768,11 +3812,11 @@ msgstr "les deux boutons appuyés lors du démarrage.\n" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "pull_threshold must be between 1 and 32" -msgstr "" +msgstr "pull_threshold doit être entre 1 et 32" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "push_threshold must be between 1 and 32" -msgstr "" +msgstr "push_threshold doit être entre 1 et 32" #: extmod/modutimeq.c msgid "queue overflow" @@ -4191,6 +4235,11 @@ msgstr "chien de garde (watchdog) non initialisé" msgid "watchdog timeout must be greater than 0" msgstr "watchdog timeout doit être supérieur à 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "width doit être entre 2 et 8 (inclusivement), non %d" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "width doit être plus que zero" diff --git a/locale/hi.po b/locale/hi.po index fe77821334..3d81006978 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -363,6 +363,7 @@ msgstr "" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "" @@ -1091,6 +1092,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1446,9 +1452,14 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1653,6 +1664,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1724,6 +1740,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1963,6 +1983,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "" @@ -2126,6 +2154,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3308,6 +3337,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" @@ -3622,6 +3655,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4078,6 +4115,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 1c91b08927..0153dc889c 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -7,25 +7,31 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2018-10-02 16:27+0200\n" -"Last-Translator: Enrico Paganin \n" +"PO-Revision-Date: 2021-02-18 15:50+0000\n" +"Last-Translator: Luca De Filippo \n" "Language-Team: \n" "Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.5\n" #: main.c msgid "" "\n" "Code done running.\n" msgstr "" +"\n" +"Caricamento codice pronto.\n" #: main.c msgid "" "\n" "Code stopped by auto-reload.\n" msgstr "" +"\n" +"Codice fermato dall'auto-ricarica.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -33,6 +39,9 @@ msgid "" "Please file an issue with the contents of your CIRCUITPY drive at \n" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" +"\n" +"Per favore, segnala il problema con il contenuto del tuo CIRCUITPY a\n" +"https://github.com/adafruit/circuitpython/issues\n" #: py/obj.c msgid " File \"%q\"" @@ -44,7 +53,7 @@ msgstr " File \"%q\", riga %d" #: py/builtinhelp.c msgid " is of type %q\n" -msgstr "" +msgstr " è di tipo %q\n" #: main.c msgid " output:\n" @@ -60,10 +69,11 @@ msgstr "%%c necessita di int o char" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d pin indirizzo, %d pin rgb e %d tessere indicano l'altezza di %d, non %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" -msgstr "" +msgstr "%q fallito: %d" #: shared-bindings/microcontroller/Pin.c msgid "%q in use" @@ -79,15 +89,15 @@ msgstr "indice %q fuori intervallo" #: py/obj.c msgid "%q indices must be integers, not %q" -msgstr "" +msgstr "%q gli indici devono essere interi, non %q" #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" -msgstr "" +msgstr "lista %q deve essere una lista" #: shared-bindings/memorymonitor/AllocationAlarm.c msgid "%q must be >= 0" -msgstr "" +msgstr "%q deve essere >= 0" #: shared-bindings/_bleio/CharacteristicBuffer.c #: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c @@ -100,20 +110,19 @@ msgstr "slice del buffer devono essere della stessa lunghezza" #: shared-module/vectorio/Polygon.c msgid "%q must be a tuple of length 2" -msgstr "" +msgstr "%q deve essere una tupla di lunghezza 2" #: shared-bindings/canio/Match.c msgid "%q out of range" -msgstr "" +msgstr "%q oltre il limite" #: ports/atmel-samd/common-hal/microcontroller/Pin.c msgid "%q pin invalid" -msgstr "" +msgstr "%q pin non valido" #: shared-bindings/fontio/BuiltinFont.c -#, fuzzy msgid "%q should be an int" -msgstr "y dovrebbe essere un int" +msgstr "%q dovrebbe essere un int" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -122,7 +131,7 @@ msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" -msgstr "" +msgstr "%s errore 0x%x" #: py/argcheck.c msgid "'%q' argument required" @@ -130,93 +139,93 @@ msgstr "'%q' argomento richiesto" #: py/runtime.c msgid "'%q' object cannot assign attribute '%q'" -msgstr "" +msgstr "L'oggetto '%q' non può assegnare l'attributo '%q'" #: py/proto.c msgid "'%q' object does not support '%q'" -msgstr "" +msgstr "L'oggetto '%q' non supporta '%q'" #: py/obj.c msgid "'%q' object does not support item assignment" -msgstr "" +msgstr "L'oggetto '%q' non supporta l'assegnazione dell'elemento" #: py/obj.c msgid "'%q' object does not support item deletion" -msgstr "" +msgstr "L'oggetto '%q' non supporta la rimozione dell'elemento" #: py/runtime.c msgid "'%q' object has no attribute '%q'" -msgstr "" +msgstr "L'oggetto '%q' non ha attributi '%q'" #: py/runtime.c msgid "'%q' object is not an iterator" -msgstr "" +msgstr "L'oggetto '%q' non è un iteratore" #: py/objtype.c py/runtime.c msgid "'%q' object is not callable" -msgstr "" +msgstr "L'oggetto '%q' non è richiamabile" #: py/runtime.c msgid "'%q' object is not iterable" -msgstr "" +msgstr "L'oggetto '%q' non è iterabile" #: py/obj.c msgid "'%q' object is not subscriptable" -msgstr "" +msgstr "l'oggetto '%q' non è riscrivibile" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a label" -msgstr "'%s' aspetta una etichetta" +msgstr "'%s' richiede una etichetta" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a register" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede un registro" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' expects a special register" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede un registro speciale" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' expects an FPU register" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede un registro FPU" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede un indirizzo dal modulo [a, b]" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects an integer" -msgstr "'%s' aspetta un intero" +msgstr "'%s' richiede un valore intero" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' expects at most r%d" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede almeno r%d" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' aspetta un registro" +msgstr "'%s' richiede {r0, r1, ...}" #: py/emitinlinextensa.c -#, fuzzy, c-format +#, c-format msgid "'%s' integer %d is not within range %d..%d" -msgstr "intero '%s' non è nell'intervallo %d..%d" +msgstr "Valore intero '%s' %d non è nell'intervallo %d..%d" #: py/emitinlinethumb.c -#, fuzzy, c-format +#, c-format msgid "'%s' integer 0x%x does not fit in mask 0x%x" -msgstr "intero '%s' non è nell'intervallo %d..%d" +msgstr "Valore intero '%s' 0x%x non rientra nella maschera 0x%x" #: py/objstr.c msgid "'=' alignment not allowed in string format specifier" -msgstr "aligniamento '=' non è permesso per il specificatore formato string" +msgstr "Allineamento'=' non è permesso per lo specificatore formato stringa" #: shared-module/struct/__init__.c msgid "'S' and 'O' are not supported format types" @@ -233,22 +242,23 @@ msgstr "'await' al di fuori della funzione" #: py/compile.c msgid "'await', 'async for' or 'async with' outside async function" msgstr "" +"'await', 'async for' o 'async with' fuori della funzione sincronizzazione" #: py/compile.c msgid "'break' outside loop" -msgstr "'break' al di fuori del ciclo" +msgstr "'break' fuori del ciclo" #: py/compile.c msgid "'continue' outside loop" -msgstr "'continue' al di fuori del ciclo" +msgstr "'continue' fuori del ciclo" #: py/objgenerator.c msgid "'coroutine' object is not an iterator" -msgstr "" +msgstr "L'oggetto 'coroutine' non è un iteratore" #: py/compile.c msgid "'data' requires at least 2 arguments" -msgstr "'data' richiede almeno 2 argomento" +msgstr "'data' richiede almeno 2 argomenti" #: py/compile.c msgid "'data' requires integer arguments" @@ -264,7 +274,7 @@ msgstr "'return' al di fuori della funzione" #: py/compile.c msgid "'yield from' inside async function" -msgstr "" +msgstr "'yield from' è nella funzione sincronizzazione" #: py/compile.c msgid "'yield' outside function" @@ -288,29 +298,29 @@ msgstr "pow() con tre argmomenti non supportata" #: shared-module/msgpack/__init__.c msgid "64 bit types" -msgstr "" +msgstr "Tipo 64 bits" #: ports/atmel-samd/common-hal/countio/Counter.c #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "A hardware interrupt channel is already in use" -msgstr "Un canale di interrupt hardware è già in uso" +msgstr "Un canale di interruzione hardware è già in uso" #: ports/esp32s2/common-hal/analogio/AnalogIn.c msgid "ADC2 is being used by WiFi" -msgstr "" +msgstr "ADC2 sta usando il WiFi" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, fuzzy, c-format +#, c-format msgid "Address must be %d bytes long" -msgstr "la palette deve essere lunga 32 byte" +msgstr "L'indirizzo deve essere lungo %d byte" #: shared-bindings/_bleio/Address.c msgid "Address type out of range" -msgstr "" +msgstr "Tipo di indirizzo fuori intervallo" #: ports/esp32s2/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" -msgstr "" +msgstr "Tutte le periferiche CAN sono in uso" #: ports/esp32s2/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c msgid "All I2C peripherals are in use" @@ -320,13 +330,13 @@ msgstr "Tutte le periferiche I2C sono in uso" #: ports/esp32s2/common-hal/frequencyio/FrequencyIn.c #: ports/esp32s2/common-hal/rotaryio/IncrementalEncoder.c msgid "All PCNT units in use" -msgstr "" +msgstr "Tutte le unità PCNT sono in uso" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/esp32s2/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "All RX FIFOs in use" -msgstr "" +msgstr "Tutte le RX FIFO sono in uso" #: ports/esp32s2/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" @@ -343,7 +353,7 @@ msgstr "Tutti i canali eventi utilizati" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "All state machines in use" -msgstr "" +msgstr "Tutte le state machines sono in uso" #: ports/atmel-samd/audio_dma.c ports/atmel-samd/common-hal/audiobusio/PDMIn.c msgid "All sync event channels in use" @@ -365,6 +375,7 @@ msgstr "Tutti i timer per questo pin sono in uso" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Tutti i timer utilizzati" @@ -375,16 +386,16 @@ msgstr "" #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Already have all-matches listener" -msgstr "" +msgstr "Già in possesso di tutti i listener abbinati" #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" -msgstr "" +msgstr "Già in funzione" #: ports/esp32s2/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" -msgstr "" +msgstr "Già in ricerca di collegamenti WiFi" #: ports/cxd56/common-hal/analogio/AnalogIn.c msgid "AnalogIn not supported on given pin" @@ -416,24 +427,24 @@ msgstr "Array deve avere mezzoparole (typo 'H')" #: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." -msgstr "Valori di Array dovrebbero essere bytes singulari" +msgstr "I valori dell'Array dovrebbero essere bytes singoli." #: shared-bindings/microcontroller/Pin.c msgid "At most %d %q may be specified (not %d)" -msgstr "" +msgstr "Almeno %d %q devono essere specificati (non %d)" #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" -msgstr "" +msgstr "Provo ad allocare %d blocchi" #: supervisor/shared/safe_mode.c msgid "Attempted heap allocation when MicroPython VM not running." -msgstr "" +msgstr "Provo l'allocazione quando MicroPython VM non è attivo." #: shared-bindings/wifi/Radio.c msgid "Authentication failure" -msgstr "" +msgstr "Autenticazione Fallita" #: main.c msgid "Auto-reload is off.\n" @@ -454,7 +465,7 @@ msgstr "" #: shared-module/displayio/Display.c #: shared-module/framebufferio/FramebufferDisplay.c msgid "Below minimum frame rate" -msgstr "" +msgstr "Al di sotto del frame rate minimo" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must share a clock unit" @@ -464,15 +475,15 @@ msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "Bit depth must be from 1 to 6 inclusive, not %d" -msgstr "" +msgstr "La profondità dei bit deve essere inclusiva da 1 a 6, non %d" #: shared-bindings/audiobusio/PDMIn.c msgid "Bit depth must be multiple of 8." -msgstr "La profondità di bit deve essere multipla di 8." +msgstr "La profondità di bit deve essere un multiplo di 8." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" -msgstr "" +msgstr "Sia RX che TX richiedono il controllo del flow" #: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c msgid "Both pins must support hardware interrupts" @@ -482,21 +493,21 @@ msgstr "Entrambi i pin devono supportare gli interrupt hardware" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "Brightness must be 0-1.0" -msgstr "" +msgstr "La luminosità deve essere tra 0-1.0" #: shared-bindings/supervisor/__init__.c msgid "Brightness must be between 0 and 255" -msgstr "La luminosità deve essere compreso tra 0 e 255" +msgstr "La luminosità deve essere compresa tra 0 e 255" #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Brightness not adjustable" -msgstr "Illiminazione non è regolabile" +msgstr "Luminosità non è regolabile" #: shared-bindings/_bleio/UUID.c #, c-format msgid "Buffer + offset too small %d %d %d" -msgstr "" +msgstr "Buffer + offset troppo piccolo %d %d %d" #: shared-module/usb_hid/Device.c #, c-format @@ -506,26 +517,26 @@ msgstr "Buffer di lunghezza non valida. Dovrebbe essere di %d bytes." #: shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." -msgstr "" +msgstr "Buffer non è un array di bites." #: ports/cxd56/common-hal/camera/Camera.c shared-bindings/displayio/Display.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is too small" -msgstr "" +msgstr "Buffer troppo piccolo" #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #, c-format msgid "Buffer length %d too big. It must be less than %d" -msgstr "" +msgstr "Lunghezza Buffer %d troppo grande. Deve essere meno di %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c #: ports/cxd56/common-hal/sdioio/SDCard.c shared-module/sdcardio/SDCard.c msgid "Buffer length must be a multiple of 512" -msgstr "" +msgstr "La lunghezza del buffer deve essere un multiplo di 512" #: ports/stm/common-hal/sdioio/SDCard.c msgid "Buffer must be a multiple of 512 bytes" -msgstr "" +msgstr "Il buffer deve essere un multiplo di 512 bytes" #: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c msgid "Buffer must be at least length 1" @@ -533,40 +544,39 @@ msgstr "Il buffer deve essere lungo almeno 1" #: ports/nrf/common-hal/_bleio/PacketBuffer.c msgid "Buffer too large and unable to allocate" -msgstr "" +msgstr "Buffer troppo grande ed impossibile allocare" #: shared-bindings/_bleio/PacketBuffer.c #, c-format msgid "Buffer too short by %d bytes" -msgstr "" +msgstr "Buffer troppo piccolo di %d bytes" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c #: ports/esp32s2/common-hal/displayio/ParallelBus.c #: ports/nrf/common-hal/displayio/ParallelBus.c -#, fuzzy, c-format +#, c-format msgid "Bus pin %d is already in use" -msgstr "DAC già in uso" +msgstr "Bus pin %d è già in uso" #: shared-bindings/_bleio/UUID.c -#, fuzzy msgid "Byte buffer must be 16 bytes." -msgstr "i buffer devono essere della stessa lunghezza" +msgstr "I buffer byte devono essere di almeno 16 bytes." #: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Bytes must be between 0 and 255." -msgstr "I byte devono essere compresi tra 0 e 255" +msgstr "I byte devono essere compresi tra 0 e 255." #: shared-bindings/aesio/aes.c msgid "CBC blocks must be multiples of 16 bytes" -msgstr "" +msgstr "I blocchi CBC devono essere multipli di 16 bytes" #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c msgid "CRC or checksum was invalid" -msgstr "" +msgstr "CRC o controllo totale è risultato non valido" #: py/objtype.c msgid "Call super().__init__() before accessing native object." -msgstr "" +msgstr "Chiama super().__init__() prima di accedere ad un oggetto nativo." #: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." @@ -1106,6 +1116,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1465,9 +1480,14 @@ msgstr "Nessun DAC sul chip" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Nessun canale DMA trovato" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1676,6 +1696,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "L'oversampling deve essere multiplo di 8." @@ -1752,6 +1777,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c #, fuzzy msgid "Plus any modules on the filesystem\n" @@ -1995,6 +2024,14 @@ msgstr "Suddivisione con sotto-catture" msgid "Stack size must be at least 256" msgstr "La dimensione dello stack deve essere almeno 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Metodi mancanti readinto() o write() allo stream." @@ -2158,6 +2195,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Ipossibilitato ad allocare buffer per la conversione con segno" @@ -3358,6 +3396,10 @@ msgstr "allocazione di memoria fallita, allocando %u byte" msgid "memory allocation failed, heap is locked" msgstr "allocazione di memoria fallita, l'heap è bloccato" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "modulo non trovato" @@ -3679,6 +3721,10 @@ msgstr "pop sun un PulseIn vuoto" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "il terzo argomento di pow() non può essere 0" @@ -4139,6 +4185,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/ja.po b/locale/ja.po index 0fb8a6f481..2616789f4b 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -368,6 +368,7 @@ msgstr "このピン用の全てのタイマが使用中" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "全てのタイマーが使用中" @@ -1104,6 +1105,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1459,9 +1465,14 @@ msgstr "チップにDACがありません" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "DMAチャネルが見つかりません" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1668,6 +1679,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "オーバーサンプルは8の倍数でなければなりません" @@ -1740,6 +1756,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1979,6 +1999,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "スタックサイズは少なくとも256以上でなければなりません" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "ストリームにreadinto()またはwrite()メソッドがありません" @@ -2149,6 +2177,7 @@ msgstr "UUIDの値がstr, int, bufferのいずれでもありません" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3336,6 +3365,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "メモリ確保に失敗。ヒープがロックされています" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "モジュールが見つかりません" @@ -3652,6 +3685,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "pow()の3つ目の引数は0にできません" @@ -4109,6 +4146,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "watchdogのtimeoutは0以上でなければなりません" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index ce662ad5f4..26810f87e5 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -364,6 +364,7 @@ msgstr "핀의 모든 타이머가 사용 중입니다" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "모든 타이머가 사용 중입니다" @@ -1094,6 +1095,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1449,9 +1455,14 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1656,6 +1667,11 @@ msgstr "" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "" @@ -1727,6 +1743,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "" @@ -1966,6 +1986,14 @@ msgstr "" msgid "Stack size must be at least 256" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "" @@ -2130,6 +2158,7 @@ msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "" @@ -3312,6 +3341,10 @@ msgstr "" msgid "memory allocation failed, heap is locked" msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "" @@ -3626,6 +3659,10 @@ msgstr "" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -4082,6 +4119,11 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 821f338cac..463a70da25 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -366,6 +366,7 @@ msgstr "Alle timers voor deze pin zijn in gebruik" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Alle timers zijn in gebruik" @@ -1105,6 +1106,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "De initialisatie is mislukt vanwege een gebrek aan geheugen" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "Invoer duurt te lang" @@ -1460,9 +1466,14 @@ msgstr "Geen DAC op de chip" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Geen DMA kanaal gevonden" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1673,6 +1684,11 @@ msgstr "" msgid "Out of sockets" msgstr "Geen sockets meer beschikbaar" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Oversample moet een meervoud van 8 zijn." @@ -1750,6 +1766,10 @@ msgstr "" "gebruikt. Als dit niet kan worden vermeden, geef dan het argument " "allow_inefficient=True aan de constructor" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "En iedere module in het bestandssysteem\n" @@ -1995,6 +2015,14 @@ msgstr "Splitting met sub-captures" msgid "Stack size must be at least 256" msgstr "Stack grootte moet op zijn minst 256 zijn" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Stream mist readinto() of write() methode." @@ -2168,6 +2196,7 @@ msgstr "UUID waarde is geen str, int, of byte buffer" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Niet in staat buffers voor gesigneerde conversie te alloceren" @@ -3369,6 +3398,10 @@ msgstr "geheugentoewijzing mislukt, %u bytes worden toegewezen" msgid "memory allocation failed, heap is locked" msgstr "geheugentoewijzing mislukt, heap is vergrendeld" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "module niet gevonden" @@ -3684,6 +3717,10 @@ msgstr "pop van een lege PulseIn" msgid "pop from empty %q" msgstr "pop van een lege %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "derde argument van pow() mag geen 0 zijn" @@ -4142,6 +4179,11 @@ msgstr "watchdog niet geïnitialiseerd" msgid "watchdog timeout must be greater than 0" msgstr "watchdog time-out moet groter zijn dan 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "breedte moet groter dan nul zijn" diff --git a/locale/pl.po b/locale/pl.po index 67eb288167..bf914aefb3 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-01-27 01:31+0000\n" +"PO-Revision-Date: 2021-02-10 21:50+0000\n" "Last-Translator: Maciej Stankiewicz \n" "Language-Team: pl\n" "Language: pl\n" @@ -368,6 +368,7 @@ msgstr "Wszystkie timery tej nóżki w użyciu" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Wszystkie timery w użyciu" @@ -1104,6 +1105,11 @@ msgstr "" msgid "Initialization failed due to lack of memory" msgstr "Inicjalizacja nie powiodła się z powodu braku pamięci" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "" @@ -1460,9 +1466,14 @@ msgstr "Brak DAC" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Nie znaleziono kanału DMA" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1667,6 +1678,11 @@ msgstr "Brak pamięci" msgid "Out of sockets" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Nadpróbkowanie musi być wielokrotnością 8." @@ -1738,6 +1754,10 @@ msgid "" "constructor" msgstr "" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Oraz moduły w systemie plików\n" @@ -1977,6 +1997,14 @@ msgstr "Podział z podgrupami" msgid "Stack size must be at least 256" msgstr "Stos musi mieć co najmniej 256 bajtów" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Strumień nie ma metod readinto() lub write()." @@ -2140,6 +2168,7 @@ msgstr "UUID nie jest typu str, int lub bytes" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Nie udała się alokacja buforów do konwersji ze znakiem" @@ -3329,6 +3358,10 @@ msgstr "alokacja pamięci nie powiodła się, alokowano %u bajtów" msgid "memory allocation failed, heap is locked" msgstr "alokacja pamięci nie powiodła się, sterta zablokowana" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "brak modułu" @@ -3644,6 +3677,10 @@ msgstr "pop z pustego PulseIn" msgid "pop from empty %q" msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "trzeci argument pow() nie może być 0" @@ -4101,9 +4138,14 @@ msgstr "" msgid "watchdog timeout must be greater than 0" msgstr "" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" -msgstr "" +msgstr "szerokość musi być większa niż zero" #: ports/esp32s2/common-hal/wifi/Radio.c msgid "wifi is not enabled" @@ -4123,7 +4165,7 @@ msgstr "" #: extmod/ulab/code/vector/vectorise.c msgid "wrong input type" -msgstr "" +msgstr "nieprawidłowy typ wejścia" #: extmod/ulab/code/ulab_create.c py/objstr.c msgid "wrong number of arguments" @@ -4139,7 +4181,7 @@ msgstr "zły typ operandu" #: extmod/ulab/code/vector/vectorise.c msgid "wrong output type" -msgstr "" +msgstr "nieprawidłowy typ wyjścia" #: shared-module/displayio/Shape.c msgid "x value out of bounds" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 9826ac757a..c283cdda81 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-02-05 15:41+0000\n" +"PO-Revision-Date: 2021-02-21 22:27+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.5-dev\n" +"X-Generator: Weblate 4.5\n" #: main.c msgid "" @@ -376,6 +376,7 @@ msgstr "Todos os temporizadores para este pino estão em uso" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Todos os temporizadores em uso" @@ -1123,6 +1124,13 @@ msgstr "O tamanho do programa Init é inválido" msgid "Initialization failed due to lack of memory" msgstr "A inicialização falhou devido à falta de memória" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" +"O comprimento do buffer de entrada (%d) deve ser um múltiplo da contagem dos " +"fios (%d)" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "A entrada está demorando demais" @@ -1478,9 +1486,14 @@ msgstr "Nenhum DAC no chip" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Nenhum canal DMA foi encontrado" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "Nenhum temporizador DMA foi encontrado" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1692,6 +1705,11 @@ msgstr "Sem memória" msgid "Out of sockets" msgstr "Sem soquetes" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "O buffer de saída deve ter ao menos %d bytes" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "A superamostragem deve ser um múltiplo de 8." @@ -1770,6 +1788,10 @@ msgstr "" "ideal. Caso isso não possa ser evitado, passe allow_inefficient=True ao " "construtor" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "Os pinos devem compartilhar a fatia do PWM" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Além de quaisquer módulos no sistema de arquivos\n" @@ -2019,6 +2041,14 @@ msgstr "Divisão com sub-capturas" msgid "Stack size must be at least 256" msgstr "O tamanho da pilha deve ser pelo menos 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "O estéreo à esquerda deve estar no canal PWM A" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "O estéreo à direita deve estar no canal PWM B" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Transmita o método ausente readinto() ou write()." @@ -2196,6 +2226,7 @@ msgstr "O valor UUID não é um buffer str, int ou byte" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Não é possível alocar buffers para conversão assinada" @@ -3405,6 +3436,10 @@ msgstr "" "falha na alocação de memória, a área de alocação dinâmica de variáveis " "(heap) está bloqueada" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "memoryview: o comprimento não é um múltiplo do tamanho dos itens" + #: py/builtinimport.c msgid "module not found" msgstr "o módulo não foi encontrado" @@ -3724,6 +3759,10 @@ msgstr "pop a partir de um PulseIn vazio" msgid "pop from empty %q" msgstr "pop a partir do %q vazio" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "a porta deve ser > = 0" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "O terceiro argumento pow() não pode ser 0" @@ -4182,6 +4221,11 @@ msgstr "o watchdog não foi inicializado" msgid "watchdog timeout must be greater than 0" msgstr "o tempo limite do watchdog deve ser maior que 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "a largura deve ser entre 2 a 8 (inclusive), não %d" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "a largura deve ser maior que zero" diff --git a/locale/sv.po b/locale/sv.po index 2ec0499c50..7b82d7a7f2 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-02-05 19:47+0000\n" +"PO-Revision-Date: 2021-02-21 22:27+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5-dev\n" +"X-Generator: Weblate 4.5\n" #: main.c msgid "" @@ -371,6 +371,7 @@ msgstr "Alla timers för denna pinne är i bruk" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Alla timers används" @@ -1110,6 +1111,11 @@ msgstr "Storlek på init-program ogiltigt" msgid "Initialization failed due to lack of memory" msgstr "Initieringen misslyckades på grund av minnesbrist" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "indatabuffertlängd (%d) måste vara en multipel av antal strand (%d)" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "Indata tar för lång tid" @@ -1466,9 +1472,14 @@ msgstr "Ingen DAC på chipet" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Ingen DMA-kanal hittades" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "Ingen DMA pacing timer hittades" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1678,6 +1689,11 @@ msgstr "Slut på minne" msgid "Out of sockets" msgstr "Slut på sockets" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "Utdatabuffert måste vara minst %d byte" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Översampling måste vara multipel av 8." @@ -1754,6 +1770,10 @@ msgstr "" "%d byte. Om detta inte kan undvikas, skicka allow_inefficient=True till " "konstruktorn" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "Pinnar måste dela PWM-segment" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Plus eventuella moduler i filsystemet\n" @@ -1999,6 +2019,14 @@ msgstr "Splitting med sub-captures" msgid "Stack size must be at least 256" msgstr "Stackstorleken måste vara minst 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "Vänster stereokanal måste använda PWM kanal A" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "Höger stereokanal måste använda PWM kanal B" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Stream saknar readinto() eller write() metod." @@ -2172,6 +2200,7 @@ msgstr "UUID-värdet är inte str, int eller byte-buffert" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Det går inte att allokera buffert för signerad konvertering" @@ -3370,6 +3399,10 @@ msgstr "minnesallokering misslyckades, allokerar %u byte" msgid "memory allocation failed, heap is locked" msgstr "minnesallokeringen misslyckades, heapen är låst" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "memoryview: längden är inte en multipel av itemsize" + #: py/builtinimport.c msgid "module not found" msgstr "modulen hittades inte" @@ -3685,6 +3718,10 @@ msgstr "pop från en tom PulseIn" msgid "pop from empty %q" msgstr "pop från tom %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "port måste vara >= 0" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "pow() 3: e argument kan inte vara 0" @@ -4143,6 +4180,11 @@ msgstr "watchdog är inte initierad" msgid "watchdog timeout must be greater than 0" msgstr "watchdog timeout måste vara större än 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "width måste vara mellan 2 och 8, inte %d" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "width måste vara större än noll" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index fa175ca571..5a08380002 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-02-02 03:38+0000\n" +"PO-Revision-Date: 2021-02-09 14:03+0000\n" "Last-Translator: hexthat \n" "Language-Team: Chinese Hanyu Pinyin\n" "Language: zh_Latn_pinyin\n" @@ -373,6 +373,7 @@ msgstr "Cǐ yǐn jiǎo de suǒyǒu jìshí qì zhèngzài shǐyòng" #: ports/esp32s2/common-hal/pulseio/PulseOut.c #: ports/nrf/common-hal/audiopwmio/PWMAudioOut.c #: ports/nrf/common-hal/pulseio/PulseIn.c ports/nrf/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c #: ports/stm/peripherals/timers.c shared-bindings/pwmio/PWMOut.c msgid "All timers in use" msgstr "Suǒyǒu jìshí qì shǐyòng" @@ -645,7 +646,7 @@ msgstr "Wúfǎ chóng zhì wèi bootloader, yīnwèi méiyǒu bootloader cúnzà #: ports/esp32s2/common-hal/socketpool/Socket.c msgid "Cannot set socket options" -msgstr "" +msgstr "wú fǎ shè zhì tào jiē zì xuǎn xiàng" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -1109,6 +1110,11 @@ msgstr "Init chéng xù dà xiǎo wú xiào" msgid "Initialization failed due to lack of memory" msgstr "yóu yú nèi cún bù zú, chū shǐ huà shī bài" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "" + #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" msgstr "Shūrù shíjiānguò zhǎng" @@ -1465,9 +1471,14 @@ msgstr "Méiyǒu DAC zài xīnpiàn shàng de" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" msgstr "Wèi zhǎodào DMA píndào" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" + #: shared-module/adafruit_bus_device/I2CDevice.c #, c-format msgid "No I2C device at address: %x" @@ -1558,7 +1569,7 @@ msgstr "chéng xù zhōng wèi tuì chū" #: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "" +msgstr "zài SDA huò SCL shàng wèi zhǎo dào shàng lā; jiǎn chá nín de xiàn lù" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" @@ -1677,6 +1688,11 @@ msgstr "nèi cún bù zú" msgid "Out of sockets" msgstr "tào jiē zì wài" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Output buffer must be at least %d bytes" +msgstr "" + #: shared-bindings/audiobusio/PDMIn.c msgid "Oversample must be multiple of 8." msgstr "Guò cǎiyàng bìxū shì 8 de bèishù." @@ -1752,6 +1768,10 @@ msgstr "" "duōzì jié. Rúguǒ wúfǎ bìmiǎn, qǐng jiāng allow_inefficient = True chuándì " "gěigòuzào hánshù" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" + #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n" @@ -1828,7 +1848,7 @@ msgstr "RNG chūshǐhuà cuòwù" #: ports/nrf/common-hal/busio/UART.c msgid "RS485 Not yet supported on this device" -msgstr "" +msgstr "RS485 cǐ shè bèi shàng bù zhī chí" #: ports/esp32s2/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1994,6 +2014,14 @@ msgstr "Yǔ zi bǔhuò fēnliè" msgid "Stack size must be at least 256" msgstr "Duīzhàn dàxiǎo bìxū zhìshǎo 256" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo left must be on PWM channel A" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Stereo right must be on PWM channel B" +msgstr "" + #: shared-bindings/multiterminal/__init__.c msgid "Stream missing readinto() or write() method." msgstr "Liú quēshǎo readinto() huò write() fāngfǎ." @@ -2166,6 +2194,7 @@ msgstr "UUID zhí bùshì str,int huò zì jié huǎnchōng qū" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Unable to allocate buffers for signed conversion" msgstr "Wúfǎ fēnpèi huǎnchōng qū yòng yú qiānmíng zhuǎnhuàn" @@ -3364,6 +3393,10 @@ msgstr "nèicún fēnpèi shībài, fēnpèi %u zì jié" msgid "memory allocation failed, heap is locked" msgstr "jìyì tǐ fēnpèi shībài, duī bèi suǒdìng" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "" + #: py/builtinimport.c msgid "module not found" msgstr "zhǎo bù dào mókuài" @@ -3678,6 +3711,10 @@ msgstr "cóng kōng mài chōng tán chū" msgid "pop from empty %q" msgstr "cóng kōng %q dànchū" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "port must be >= 0" +msgstr "duān kǒu bì xū wéi >= 0" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "pow() 3 cān shǔ bùnéng wéi 0" @@ -4136,6 +4173,11 @@ msgstr "wèi chū shǐ huà jiān shì qì" msgid "watchdog timeout must be greater than 0" msgstr "kān mén gǒu chāoshí bìxū dàyú 0" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "width must be from 2 to 8 (inclusive), not %d" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "width must be greater than zero" msgstr "kuāndù bìxū dàyú líng" diff --git a/main.c b/main.c index 7bfa565df4..7df6e293aa 100755 --- a/main.c +++ b/main.c @@ -69,6 +69,19 @@ #include "shared-bindings/alarm/__init__.h" #endif +#if CIRCUITPY_BLEIO +#include "shared-bindings/_bleio/__init__.h" +#include "supervisor/shared/bluetooth.h" +#endif + +#if CIRCUITPY_BOARD +#include "shared-module/board/__init__.h" +#endif + +#if CIRCUITPY_CANIO +#include "common-hal/canio/CAN.h" +#endif + #if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" #endif @@ -81,17 +94,8 @@ #include "shared-module/network/__init__.h" #endif -#if CIRCUITPY_BOARD -#include "shared-module/board/__init__.h" -#endif - -#if CIRCUITPY_BLEIO -#include "shared-bindings/_bleio/__init__.h" -#include "supervisor/shared/bluetooth.h" -#endif - -#if CIRCUITPY_CANIO -#include "common-hal/canio/CAN.h" +#if CIRCUITPY_USB_CDC +#include "shared-module/usb_cdc/__init__.h" #endif #if CIRCUITPY_WIFI diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 58c1c0d60e..48724af0c8 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -122,7 +122,7 @@ CFLAGS += -ftree-vrp $(echo PERIPHERALS_CHIP_FAMILY=$(PERIPHERALS_CHIP_FAMILY)) #Debugging/Optimization ifeq ($(DEBUG), 1) - CFLAGS += -ggdb3 -Og + CFLAGS += -ggdb3 -Og -Os # You may want to disable -flto if it interferes with debugging. CFLAGS += -flto -flto-partition=none # You may want to enable these flags to make setting breakpoints easier. diff --git a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk index f976dfe787..295d7b2aea 100644 --- a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk +++ b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk @@ -15,8 +15,7 @@ CIRCUITPY_FULL_BUILD = 0 CIRCUITPY_USB_MIDI = 0 SUPEROPT_GC = 0 - -CFLAGS_INLINE_LIMIT = 60 +SUPEROPT_VM = 0 CIRCUITPY_GAMEPAD = 1 CIRCUITPY_BUSDEVICE = 1 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk index 36d463697d..1fd96b0aee 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk @@ -9,5 +9,6 @@ CHIP_FAMILY = samd21 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + SUPEROPT_GC = 0 SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk index 20307fc051..fabe52ce23 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk @@ -12,4 +12,3 @@ CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 -CFLAGS_INLINE_LIMIT = 40 diff --git a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk index 07b1b98002..c16c53e6d6 100644 --- a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk +++ b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.mk @@ -11,5 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 +SUPEROPT_VM = 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 6a2c896197..ec037837e5 100644 --- a/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bast_pro_mini_m0/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk index ae0b6837c0..6d240686d7 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk @@ -22,7 +22,7 @@ CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 SUPEROPT_GC = 0 -CFLAGS_INLINE_LIMIT = 40 +SUPEROPT_VM = 0 # Include these Python libraries in firmware. diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk index aace5c0cb5..2a97636ded 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -25,25 +25,10 @@ CIRCUITPY_RTC = 0 CIRCUITPY_VECTORIO = 0 SUPEROPT_GC = 0 -CFLAGS_INLINE_LIMIT = 55 +SUPEROPT_VM = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), ja) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 15 -endif -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/cp_sapling_m0/mpconfigboard.mk b/ports/atmel-samd/boards/cp_sapling_m0/mpconfigboard.mk index 861a0a5f7d..3799d7ef73 100644 --- a/ports/atmel-samd/boards/cp_sapling_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/cp_sapling_m0/mpconfigboard.mk @@ -11,14 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk index ae05d32f2c..22b55f6fd5 100644 --- a/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datum_distance/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk index 6fd05f403b..7e99182912 100644 --- a/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datum_imu/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/datum_light/mpconfigboard.mk b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk index d42a7869de..5916f23b31 100644 --- a/ports/atmel-samd/boards/datum_light/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datum_light/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk index d92cbc71b3..1065fb50aa 100644 --- a/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datum_weather/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/dynalora_usb/board.c b/ports/atmel-samd/boards/dynalora_usb/board.c new file mode 100644 index 0000000000..84960e73cf --- /dev/null +++ b/ports/atmel-samd/boards/dynalora_usb/board.c @@ -0,0 +1,37 @@ +/* + * 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 "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.h b/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.h new file mode 100644 index 0000000000..12359ce8f6 --- /dev/null +++ b/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.h @@ -0,0 +1,36 @@ +#define MICROPY_HW_BOARD_NAME "DynaLoRa_USB" +#define MICROPY_HW_MCU_NAME "samd21e18" + +#define MICROPY_HW_LED_STATUS (&pin_PA27) +#define MICROPY_HW_NEOPIXEL (&pin_PA19) + +#define SPI_FLASH_MOSI_PIN &pin_PA04 +#define SPI_FLASH_MISO_PIN &pin_PA05 +#define SPI_FLASH_SCK_PIN &pin_PA07 +#define SPI_FLASH_CS_PIN &pin_PA06 + +// These are pins not to reset. +#define MICROPY_PORT_A (0) +#define MICROPY_PORT_B (0) +#define MICROPY_PORT_C (0) + +#define DEFAULT_I2C_BUS_SCL (&pin_PA01) +#define DEFAULT_I2C_BUS_SDA (&pin_PA00) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA17) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA16) +#define DEFAULT_SPI_BUS_MISO (&pin_PA18) + +#define DEFAULT_UART_BUS_RX (&pin_PA00) +#define DEFAULT_UART_BUS_TX (&pin_PA01) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA23 1 +#define IGNORE_PIN_PA24 1 + +// Not connected +#define IGNORE_PIN_PA08 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA28 1 diff --git a/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.mk b/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.mk new file mode 100644 index 0000000000..ac14e73956 --- /dev/null +++ b/ports/atmel-samd/boards/dynalora_usb/mpconfigboard.mk @@ -0,0 +1,39 @@ +USB_VID = 0x04D8 +USB_PID = 0xEA2A +USB_PRODUCT = "DynaLoRa_USB" +USB_MANUFACTURER = "BHDynamics" + +CHIP_VARIANT = SAMD21E18A +CHIP_FAMILY = samd21 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICE_COUNT = 1 +EXTERNAL_FLASH_DEVICES = GD25Q32C +LONGINT_IMPL = MPZ + +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FULL_BUILD = 0 + +SUPEROPT_GC = 0 + +CFLAGS_BOARD = --param max-inline-insns-auto=15 +ifeq ($(TRANSLATION), zh_Latn_pinyin) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +endif +ifeq ($(TRANSLATION), ja) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +endif +ifeq ($(TRANSLATION), de_DE) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CFLAGS_INLINE_LIMIT = 35 +SUPEROPT_VM = 0 +endif + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM9x +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/atmel-samd/boards/dynalora_usb/pins.c b/ports/atmel-samd/boards/dynalora_usb/pins.c new file mode 100644 index 0000000000..25f4985432 --- /dev/null +++ b/ports/atmel-samd/boards/dynalora_usb/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA30) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PA31) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_RADIO_CS), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RADIO_INT), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_RADIO_RESET), MP_ROM_PTR(&pin_PA10) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA00) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA00) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI1), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_MISO1), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_SCK1), MP_ROM_PTR(&pin_PA01) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_PA15) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk index e45b5aae35..ffe76d9307 100644 --- a/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk +++ b/ports/atmel-samd/boards/escornabot_makech/mpconfigboard.mk @@ -12,3 +12,4 @@ CIRCUITPY_FULL_BUILD = 0 CIRCUITPY_RTC = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk index 69ebdfc237..183a80ffa4 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/fluff_m0/mpconfigboard.mk b/ports/atmel-samd/boards/fluff_m0/mpconfigboard.mk index c040eb4304..52fcaec020 100644 --- a/ports/atmel-samd/boards/fluff_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/fluff_m0/mpconfigboard.mk @@ -11,9 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk index e1c0f4b9a7..9d086c8f59 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk @@ -11,14 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index 2b211abd4e..6950378d53 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -25,22 +25,8 @@ CIRCUITPY_VECTORIO = 0 CFLAGS_INLINE_LIMIT = 55 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), ja) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk index 09804bc4e7..3882e780eb 100644 --- a/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ndgarage_ndbit6/mpconfigboard.mk @@ -12,3 +12,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/ndgarage_ndbit6_v2/mpconfigboard.mk b/ports/atmel-samd/boards/ndgarage_ndbit6_v2/mpconfigboard.mk index 193a0cf991..4ae1d8741d 100644 --- a/ports/atmel-samd/boards/ndgarage_ndbit6_v2/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ndgarage_ndbit6_v2/mpconfigboard.mk @@ -12,3 +12,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk index ab8065a9c5..8607385d22 100644 --- a/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/neopixel_trinkey_m0/mpconfigboard.mk @@ -9,8 +9,6 @@ CHIP_FAMILY = samd21 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE -SUPEROPT_GC = 0 - CIRCUITPY_ANALOGIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 @@ -28,16 +26,8 @@ CIRCUITPY_USB_MIDI = 1 CIRCUITPY_TOUCHIO = 1 CIRCUITPY_FULL_BUILD = 0 -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 +SUPEROPT_GC = 0 SUPEROPT_VM = 0 -endif # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk index fadcc21448..8b2ac7ff78 100644 --- a/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew10/mpconfigboard.mk @@ -20,12 +20,6 @@ CIRCUITPY_SAMD = 0 CIRCUITPY_USB_MIDI = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/pew-pewpew-standalone-10.x - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/picoplanet/mpconfigboard.mk b/ports/atmel-samd/boards/picoplanet/mpconfigboard.mk index da97b90cc2..e931553747 100644 --- a/ports/atmel-samd/boards/picoplanet/mpconfigboard.mk +++ b/ports/atmel-samd/boards/picoplanet/mpconfigboard.mk @@ -11,14 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk index 8b7066ac7a..b8ae779216 100644 --- a/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pirkey_m0/mpconfigboard.mk @@ -21,12 +21,11 @@ CIRCUITPY_SAMD = 0 CIRCUITPY_USB_MIDI = 1 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_FULL_BUILD = 0 -# Make more room. + SUPEROPT_GC = 0 +SUPEROPT_VM = 0 # Include these Python libraries in firmware. # FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote - -CFLAGS_BOARD = --param max-inline-insns-auto=12 diff --git a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk index 4484b4ed94..1a73ade94d 100644 --- a/ports/atmel-samd/boards/pyruler/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pyruler/mpconfigboard.mk @@ -11,10 +11,6 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 CIRCUITPY_COUNTIO = 0 CIRCUITPY_RTC = 0 -SUPEROPT_GC = 0 -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk index e100e2da62..c214006ead 100644 --- a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 diff --git a/ports/atmel-samd/boards/serpente/mpconfigboard.mk b/ports/atmel-samd/boards/serpente/mpconfigboard.mk index 09036875f1..1f2c83316c 100644 --- a/ports/atmel-samd/boards/serpente/mpconfigboard.mk +++ b/ports/atmel-samd/boards/serpente/mpconfigboard.mk @@ -17,18 +17,4 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_BUSDEVICE = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 -ifeq ($(TRANSLATION), zh_Latn_pinyin) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), ja) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -endif -ifeq ($(TRANSLATION), de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 SUPEROPT_VM = 0 -endif diff --git a/ports/atmel-samd/boards/shirtty/mpconfigboard.mk b/ports/atmel-samd/boards/shirtty/mpconfigboard.mk index 0b56e9ae02..70fe447232 100644 --- a/ports/atmel-samd/boards/shirtty/mpconfigboard.mk +++ b/ports/atmel-samd/boards/shirtty/mpconfigboard.mk @@ -13,5 +13,4 @@ CIRCUITPY_I2CPERIPHERAL = 1 CIRCUITPY_TOUCHIO = 0 SUPEROPT_GC = 0 - -CFLAGS_BOARD = --param max-inline-insns-auto=15 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk index 22e2059a93..435ee87fde 100644 --- a/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_qwiic_micro_no_flash/mpconfigboard.mk @@ -10,4 +10,6 @@ INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk index 3104be0a0f..bafcc02a2b 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk @@ -10,10 +10,5 @@ INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 -ifeq ($(TRANSLATION),de_DE) -RELEASE_NEEDS_CLEAN_BUILD = 1 -CFLAGS_INLINE_LIMIT = 35 -SUPEROPT_VM = 0 -endif - SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk index 9460d0009b..aef38661be 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/mpconfigboard.mk @@ -11,3 +11,4 @@ LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk index 1f88fbeade..6595fa164d 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.mk @@ -12,4 +12,3 @@ CIRCUITPY_FULL_BUILD = 0 SUPEROPT_GC = 0 SUPEROPT_VM = 0 -CFLAGS_INLINE_LIMIT = 45 diff --git a/ports/atmel-samd/boards/uchip/mpconfigboard.mk b/ports/atmel-samd/boards/uchip/mpconfigboard.mk index d08690a15a..d6ba805b14 100644 --- a/ports/atmel-samd/boards/uchip/mpconfigboard.mk +++ b/ports/atmel-samd/boards/uchip/mpconfigboard.mk @@ -10,7 +10,5 @@ INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 -# Always use aggressive inlining -CFLAGS_INLINE_LIMIT = 45 - SUPEROPT_GC = 0 +SUPEROPT_VM = 0 diff --git a/ports/atmel-samd/common-hal/_pew/PewPew.c b/ports/atmel-samd/common-hal/_pew/PewPew.c index cfdfe75d8d..1e7561ac8e 100644 --- a/ports/atmel-samd/common-hal/_pew/PewPew.c +++ b/ports/atmel-samd/common-hal/_pew/PewPew.c @@ -40,6 +40,7 @@ static uint8_t pewpew_tc_index = 0xff; +static volatile uint16_t pewpew_ticks = 0; void pewpew_interrupt_handler(uint8_t index) { @@ -52,6 +53,7 @@ void pewpew_interrupt_handler(uint8_t index) { } pew_tick(); + ++pewpew_ticks; // Clear the interrupt bit. tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; @@ -123,3 +125,7 @@ void pew_reset(void) { } MP_STATE_VM(pew_singleton) = NULL; } + +uint16_t pew_get_ticks() { + return pewpew_ticks; +} diff --git a/ports/atmel-samd/common-hal/_pew/PewPew.h b/ports/atmel-samd/common-hal/_pew/PewPew.h index da1cae0a2c..a9c3b6626c 100644 --- a/ports/atmel-samd/common-hal/_pew/PewPew.h +++ b/ports/atmel-samd/common-hal/_pew/PewPew.h @@ -44,5 +44,6 @@ typedef struct { void pew_init(void); void pewpew_interrupt_handler(uint8_t index); void pew_reset(void); +uint16_t pew_get_ticks(void); #endif // MICROPY_INCLUDED_PEW_PEWPEW_H diff --git a/ports/atmel-samd/common-hal/supervisor/Runtime.c b/ports/atmel-samd/common-hal/supervisor/Runtime.c index 6be38f216a..974f26cec1 100755 --- a/ports/atmel-samd/common-hal/supervisor/Runtime.c +++ b/ports/atmel-samd/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { return (bool) serial_bytes_available(); } diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index fb9cdf2e66..c77bf83f1e 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -18,7 +18,16 @@ ifeq ($(LONGINT_IMPL),LONGLONG) MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong endif +INTERNAL_LIBM = 1 + +USB_SERIAL_NUMBER_LENGTH = 32 + +# Number of USB endpoint pairs. +USB_NUM_EP = 8 + +###################################################################### # Put samd21-only choices here. + ifeq ($(CHIP_FAMILY),samd21) # The ?='s allow overriding in mpconfigboard.mk. @@ -39,8 +48,8 @@ CIRCUITPY_SDCARDIO ?= 0 # Not enough RAM for framebuffers CIRCUITPY_FRAMEBUFFERIO ?= 0 -# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic. -USB_MSC_EP_NUM_OUT = 1 +# Not enough room in 192kB or 256kB builds for secondary CDC. +CIRCUITPY_USB_CDC ?= 0 CIRCUITPY_ULAB = 0 @@ -55,9 +64,13 @@ CIRCUITPY_TERMINALIO = 0 endif endif # samd21 +###################################################################### +###################################################################### # Put samd51-only choices here. + ifeq ($(CHIP_FAMILY),samd51) + # No native touchio on SAMD51. CIRCUITPY_TOUCHIO_USE_NATIVE = 0 @@ -70,9 +83,4 @@ CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD) CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) endif # samd51 - -INTERNAL_LIBM = 1 - -USB_SERIAL_NUMBER_LENGTH = 32 - -USB_NUM_EP = 8 +###################################################################### diff --git a/ports/cxd56/common-hal/supervisor/Runtime.c b/ports/cxd56/common-hal/supervisor/Runtime.c index a0d9e70ab1..eeeb1430f4 100755 --- a/ports/cxd56/common-hal/supervisor/Runtime.c +++ b/ports/cxd56/common-hal/supervisor/Runtime.c @@ -27,10 +27,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { return (bool) serial_bytes_available(); } diff --git a/ports/cxd56/mpconfigport.mk b/ports/cxd56/mpconfigport.mk index e1ffc79d08..33a993ad95 100644 --- a/ports/cxd56/mpconfigport.mk +++ b/ports/cxd56/mpconfigport.mk @@ -7,6 +7,9 @@ USB_CDC_EP_NUM_DATA_IN = 1 USB_MSC_EP_NUM_OUT = 5 USB_MSC_EP_NUM_IN = 4 +# Number of USB endpoint pairs. +USB_NUM_EP = 6 + MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz CIRCUITPY_AUDIOBUSIO = 0 diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c index aaef97c7d1..4aa7b3b24f 100644 --- a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -27,6 +27,109 @@ #include "supervisor/board.h" #include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x08, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, + }; + +static void display_init(void) { + busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO36, // CLK + &pin_GPIO35, // MOSI + NULL // MISO not connected + ); + + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO37, // DC + &pin_GPIO34, // CS + &pin_GPIO38, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + + // workaround as board_init() is called before reset_port() in main.c + pwmout_reset(); + + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 52, // column start + 40, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO33, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + false, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false // SH1107_addressing + ); + + common_hal_never_reset_pin(&pin_GPIO33); // backlight pin +} void board_init(void) { // USB @@ -38,6 +141,9 @@ void board_init(void) { common_hal_never_reset_pin(&pin_GPIO43); common_hal_never_reset_pin(&pin_GPIO44); #endif /* DEBUG */ + + // Display + display_init(); } bool board_requests_safe_mode(void) { diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk index 38a7ed1fb7..79b45fd92c 100644 --- a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk @@ -2,7 +2,6 @@ USB_VID = 0x303a USB_PID = 0x8007 USB_PRODUCT = "TTGO T8 ESP32-S2" USB_MANUFACTURER = "LILYGO" -USB_DEVICES = "CDC,MSC,HID" INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c index bda0fd227a..a30c6797a5 100644 --- a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c +++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/pins.c @@ -1,4 +1,5 @@ #include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, @@ -41,13 +42,13 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO10) }, // 1.14 inch LCD ST7789 - { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO4) }, { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO33) }, { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, // Peripheral Power control { MP_ROM_QSTR(MP_QSTR_PE_POWER), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk index 5156170957..783e7ad4c7 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk @@ -2,7 +2,6 @@ USB_VID = 0x239A USB_PID = 0x80C6 USB_PRODUCT = "microS2" USB_MANUFACTURER = "microDev" -USB_DEVICES = "CDC,MSC,HID" INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk index 9857c07617..d045cc2149 100644 --- a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk +++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk @@ -2,7 +2,6 @@ USB_VID = 0x239A USB_PID = 0x80AC USB_PRODUCT = "FeatherS2" USB_MANUFACTURER = "UnexpectedMaker" -USB_DEVICES = "CDC,MSC,HID" INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk index 9857c07617..d045cc2149 100644 --- a/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk +++ b/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk @@ -2,7 +2,6 @@ USB_VID = 0x239A USB_PID = 0x80AC USB_PRODUCT = "FeatherS2" USB_MANUFACTURER = "UnexpectedMaker" -USB_DEVICES = "CDC,MSC,HID" INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ diff --git a/ports/esp32s2/boards/unexpectedmaker_tinys2/board.c b/ports/esp32s2/boards/unexpectedmaker_tinys2/board.c new file mode 100644 index 0000000000..d8fd3a0a2b --- /dev/null +++ b/ports/esp32s2/boards/unexpectedmaker_tinys2/board.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 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 "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART +#ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); +#endif /* DEBUG */ + + // SPI Flash and RAM + common_hal_never_reset_pin(&pin_GPIO26); + common_hal_never_reset_pin(&pin_GPIO27); + common_hal_never_reset_pin(&pin_GPIO28); + common_hal_never_reset_pin(&pin_GPIO29); + common_hal_never_reset_pin(&pin_GPIO30); + common_hal_never_reset_pin(&pin_GPIO31); + common_hal_never_reset_pin(&pin_GPIO32); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.h b/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.h new file mode 100644 index 0000000000..85f252328e --- /dev/null +++ b/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +//Micropython setup + +#define MICROPY_HW_BOARD_NAME "TinyS2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO1) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.mk new file mode 100644 index 0000000000..aa022e1869 --- /dev/null +++ b/ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.mk @@ -0,0 +1,23 @@ +USB_VID = 0x303A +USB_PID = 0x8002 +USB_PRODUCT = "TinyS2" +USB_MANUFACTURER = "UnexpectedMaker" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=qio +CIRCUITPY_ESP_FLASH_FREQ=80m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +# CIRCUITPY_MODULE=wroom + +CIRCUITPY_BITBANG_NEOPIXEL = 1 + +# Include these Python libraries in firmware. +# FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/esp32s2/boards/unexpectedmaker_tinys2/pins.c b/ports/esp32s2/boards/unexpectedmaker_tinys2/pins.c new file mode 100644 index 0000000000..8ca7d98649 --- /dev/null +++ b/ports/esp32s2/boards/unexpectedmaker_tinys2/pins.c @@ -0,0 +1,79 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + // { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + // { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO18) }, + // { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + // { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) }, + // { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + // { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO7) }, + // { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + // { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO6) }, + // { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + // { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + // { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + // { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + // { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + // { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + // { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + // { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + // { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + // { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO9) }, + + + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + // { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + // { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + // { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + // { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/unexpectedmaker_tinys2/sdkconfig b/ports/esp32s2/boards/unexpectedmaker_tinys2/sdkconfig new file mode 100644 index 0000000000..91447cdc2a --- /dev/null +++ b/ports/esp32s2/boards/unexpectedmaker_tinys2/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=2097152 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS2" +# end of LWIP diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 1cec5d4ae8..be435e2104 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -150,6 +150,14 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_touch_touchalarm_prepare_for_deep_sleep(); + + // Disable brownout detection, which appears to be triggered sometimes when + // waking from deep sleep. + // See https://www.esp32.com/viewtopic.php?f=13&t=19208#p71084 + // and https://github.com/adafruit/circuitpython/issues/4025#issuecomment-771027606 + // TODO: We can remove this workaround when ESP-IDF handles this. + CLEAR_PERI_REG_MASK(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_RST_ENA); + // The ESP-IDF caches the deep sleep settings and applies them before sleep. // We don't need to worry about resetting them in the interim. esp_deep_sleep_start(); diff --git a/ports/esp32s2/common-hal/microcontroller/Pin.c b/ports/esp32s2/common-hal/microcontroller/Pin.c index fca89ce8ec..ff6d0ed356 100644 --- a/ports/esp32s2/common-hal/microcontroller/Pin.c +++ b/ports/esp32s2/common-hal/microcontroller/Pin.c @@ -134,7 +134,7 @@ bool pin_number_is_free(gpio_num_t pin_number) { uint8_t offset = pin_number / 32; uint32_t mask = 1 << (pin_number % 32); - return (never_reset_pins[offset] & mask) == 0 && (in_use[offset] & mask) == 0; + return (in_use[offset] & mask) == 0; } bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c index 1cdbc90584..5f93807bb6 100644 --- a/ports/esp32s2/common-hal/socketpool/Socket.c +++ b/ports/esp32s2/common-hal/socketpool/Socket.c @@ -63,7 +63,7 @@ bool register_open_socket(socketpool_socket_obj_t* self) { } socketpool_socket_obj_t* common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self, - uint8_t* ip, uint *port) { + uint8_t* ip, uint32_t *port) { struct sockaddr_in accept_addr; socklen_t socklen = sizeof(accept_addr); int newsoc = -1; @@ -99,6 +99,7 @@ socketpool_socket_obj_t* common_hal_socketpool_socket_accept(socketpool_socket_o sock->base.type = &socketpool_socket_type; sock->num = newsoc; sock->pool = self->pool; + sock->connected = true; if (!register_open_socket(sock)) { mp_raise_OSError(MP_EBADF); @@ -113,7 +114,7 @@ socketpool_socket_obj_t* common_hal_socketpool_socket_accept(socketpool_socket_o } bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self, - const char* host, size_t hostlen, uint8_t port) { + const char* host, size_t hostlen, uint32_t port) { struct sockaddr_in bind_addr; bind_addr.sin_addr.s_addr = inet_addr(host); bind_addr.sin_family = AF_INET; @@ -144,7 +145,7 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) { } bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, - const char* host, mp_uint_t hostlen, mp_int_t port) { + const char* host, size_t hostlen, uint32_t port) { const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, @@ -202,7 +203,7 @@ bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t* self, int back } mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* self, - uint8_t* buf, mp_uint_t len, uint8_t* ip, uint *port) { + uint8_t* buf, uint32_t len, uint8_t* ip, uint *port) { struct sockaddr_in source_addr; socklen_t socklen = sizeof(source_addr); @@ -241,7 +242,7 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* se return received; } -mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, uint32_t len) { int received = 0; bool timed_out = false; @@ -273,7 +274,7 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, return received; } -mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) { +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, uint32_t len) { int sent = -1; if (self->num != -1) { // LWIP Socket @@ -290,7 +291,7 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const } mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self, - const char* host, size_t hostlen, uint8_t port, const uint8_t* buf, mp_uint_t len) { + const char* host, size_t hostlen, uint32_t port, const uint8_t* buf, uint32_t len) { // Set parameters const struct addrinfo hints = { @@ -322,6 +323,6 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self, return bytes_sent; } -void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) { +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, uint32_t timeout_ms) { self->timeout_ms = timeout_ms; } diff --git a/ports/esp32s2/common-hal/ssl/SSLSocket.c b/ports/esp32s2/common-hal/ssl/SSLSocket.c index 33507e0f4e..10c29108c4 100644 --- a/ports/esp32s2/common-hal/ssl/SSLSocket.c +++ b/ports/esp32s2/common-hal/ssl/SSLSocket.c @@ -35,19 +35,15 @@ #include "py/runtime.h" #include "supervisor/shared/tick.h" -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t* self, mp_uint_t timeout_ms) { - self->sock->timeout_ms = timeout_ms; -} - ssl_sslsocket_obj_t* common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t* self, - uint8_t* ip, uint *port) { + uint8_t* ip, uint32_t *port) { socketpool_socket_obj_t * sock = common_hal_socketpool_socket_accept(self->sock, ip, port); ssl_sslsocket_obj_t * sslsock = common_hal_ssl_sslcontext_wrap_socket(self->ssl_context, sock, false, NULL); return sslsock; } bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t* self, - const char* host, size_t hostlen, uint8_t port) { + const char* host, size_t hostlen, uint32_t port) { return common_hal_socketpool_socket_bind(self->sock, host, hostlen, port); } @@ -58,7 +54,7 @@ void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t* self) { } bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t* self, - const char* host, mp_uint_t hostlen, mp_int_t port) { + const char* host, size_t hostlen, uint32_t port) { esp_tls_cfg_t* tls_config = NULL; tls_config = &self->ssl_context->ssl_config; int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tls); @@ -104,7 +100,7 @@ bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t* self, int backlog) { return common_hal_socketpool_socket_listen(self->sock, backlog); } -mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len) { +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const uint8_t* buf, uint32_t len) { int received = 0; bool timed_out = false; int status = 0; @@ -155,7 +151,7 @@ mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const ui return received; } -mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len) { +mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t* buf, uint32_t len) { int sent = -1; sent = esp_tls_conn_write(self->tls, buf, len); @@ -174,3 +170,7 @@ mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t } return sent; } + +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t* self, uint32_t timeout_ms) { + self->sock->timeout_ms = timeout_ms; +} diff --git a/ports/esp32s2/common-hal/supervisor/Runtime.c b/ports/esp32s2/common-hal/supervisor/Runtime.c index ea663f897d..974f26cec1 100644 --- a/ports/esp32s2/common-hal/supervisor/Runtime.c +++ b/ports/esp32s2/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { - return (bool) serial_bytes_available(); +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); } diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index b273c02ee8..5073d8812d 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -28,6 +28,8 @@ CIRCUITPY_FREQUENCYIO = 1 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 1 CIRCUITPY_NVM = 1 +CIRCUITPY_PS2IO ?= 1 +CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI ?= 0 CIRCUITPY_USB_HID ?= 1 @@ -35,14 +37,9 @@ CIRCUITPY_USB_HID ?= 1 CIRCUITPY_USB_VENDOR ?= 0 CIRCUITPY_WIFI = 1 CIRCUITPY_WATCHDOG ?= 1 + CIRCUITPY_ESPIDF = 1 -ifndef CIRCUITPY_PS2IO -CIRCUITPY_PS2IO = 1 -endif - -ifndef CIRCUITPY_TOUCHIO_USE_NATIVE -CIRCUITPY_TOUCHIO_USE_NATIVE = 1 -endif - CIRCUITPY_MODULE ?= none + +USB_NUM_EP = 5 diff --git a/ports/litex/common-hal/supervisor/Runtime.c b/ports/litex/common-hal/supervisor/Runtime.c index ea663f897d..974f26cec1 100644 --- a/ports/litex/common-hal/supervisor/Runtime.c +++ b/ports/litex/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { - return (bool) serial_bytes_available(); +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); } diff --git a/ports/litex/mpconfigport.mk b/ports/litex/mpconfigport.mk index 003fb5c2c3..af6a94e64a 100644 --- a/ports/litex/mpconfigport.mk +++ b/ports/litex/mpconfigport.mk @@ -6,6 +6,9 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz # Internal math library is substantially smaller than toolchain one INTERNAL_LIBM = 1 +# Number of USB endpoint pairs. +USB_NUM_EP = 16 + # Chip supplied serial number, in bytes USB_SERIAL_NUMBER_LENGTH = 30 diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index ce7cbea7ec..00d8d9867f 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -38,6 +38,8 @@ #define LPSPI_MASTER_CLK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1)) +#define MAX_SPI_BUSY_RETRIES 100 + //arrays use 0 based numbering: SPI1 is stored at index 0 #define MAX_SPI 4 STATIC bool reserved_spi[MAX_SPI]; @@ -289,7 +291,12 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, xfer.dataSize = len; xfer.configFlags = kLPSPI_MasterPcs0; - const status_t status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + status_t status; + int retries = MAX_SPI_BUSY_RETRIES; + do { + status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + } while (status == kStatus_LPSPI_Busy && --retries > 0); + if (status != kStatus_Success) printf("%s: status %ld\r\n", __func__, status); @@ -311,7 +318,12 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self, xfer.rxData = data; xfer.dataSize = len; - const status_t status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + status_t status; + int retries = MAX_SPI_BUSY_RETRIES; + do { + status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + } while (status == kStatus_LPSPI_Busy && --retries > 0); + if (status != kStatus_Success) printf("%s: status %ld\r\n", __func__, status); @@ -333,7 +345,12 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou xfer.rxData = data_in; xfer.dataSize = len; - const status_t status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + status_t status; + int retries = MAX_SPI_BUSY_RETRIES; + do { + status = LPSPI_MasterTransferBlocking(self->spi, &xfer); + } while (status == kStatus_LPSPI_Busy && --retries > 0); + if (status != kStatus_Success) printf("%s: status %ld\r\n", __func__, status); diff --git a/ports/mimxrt10xx/common-hal/supervisor/Runtime.c b/ports/mimxrt10xx/common-hal/supervisor/Runtime.c index 6be38f216a..974f26cec1 100755 --- a/ports/mimxrt10xx/common-hal/supervisor/Runtime.c +++ b/ports/mimxrt10xx/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { return (bool) serial_bytes_available(); } diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk index b4cc9586ac..de594b14be 100644 --- a/ports/mimxrt10xx/mpconfigport.mk +++ b/ports/mimxrt10xx/mpconfigport.mk @@ -17,6 +17,9 @@ INTERNAL_LIBM = 1 USB_SERIAL_NUMBER_LENGTH = 32 USB_HIGHSPEED = 1 +# Number of USB endpoint pairs. +USB_NUM_EP = 8 + INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_AUDIOIO = 0 diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c index 1e7a319bdd..1b87b82d11 100644 --- a/ports/nrf/bluetooth/ble_uart.c +++ b/ports/nrf/bluetooth/ble_uart.c @@ -40,7 +40,7 @@ #include "shared-bindings/_bleio/Service.h" #include "shared-bindings/_bleio/UUID.h" -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_REPL_BLE static const char default_name[] = "CP-REPL"; // max 8 chars or uuid won't fit in adv data static const char NUS_UUID[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; @@ -190,4 +190,4 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) { } } -#endif // CIRCUITPY_SERIAL_BLE +#endif // CIRCUITPY_REPL_BLE diff --git a/ports/nrf/boards/TG-Watch/mpconfigboard.h b/ports/nrf/boards/TG-Watch/mpconfigboard.h index 07a607b3d7..1377c921ee 100644 --- a/ports/nrf/boards/TG-Watch/mpconfigboard.h +++ b/ports/nrf/boards/TG-Watch/mpconfigboard.h @@ -30,27 +30,27 @@ #define MICROPY_HW_BOARD_NAME "TG-Watch" #define MICROPY_HW_MCU_NAME "nRF52840" -#define MICROPY_HW_NEOPIXEL (&pin_P0_16) -#define MICROPY_HW_LED_STATUS (&pin_P1_15) - -// TG-Gui requires a deeper call stack than normal CircuitPython +// TG-Gui requires a deeper call stack than normal CircuitPython, this is intentional overkill #define CIRCUITPY_PYSTACK_SIZE 8192 // 1536 is the normal size, (32 bytes/frame * 48 frames) -#define BOARD_HAS_CRYSTAL 0 + +// the board has a 32mhz crystal but NOT a 32khz one +#define BOARD_HAS_32KHZ_XTAL 0 +#define BOARD_HAS_CRYSTAL 1 #if QSPI_FLASH_FILESYSTEM -#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) -#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) -#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) -#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) -#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) -#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) + #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) + #define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) + #define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) + #define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) + #define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) + #define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) #endif #if SPI_FLASH_FILESYSTEM -#define SPI_FLASH_MOSI_PIN &pin_P0_17 -#define SPI_FLASH_MISO_PIN &pin_P0_22 -#define SPI_FLASH_SCK_PIN &pin_P0_19 -#define SPI_FLASH_CS_PIN &pin_P0_20 + #define SPI_FLASH_MOSI_PIN &pin_P0_17 + #define SPI_FLASH_MISO_PIN &pin_P0_22 + #define SPI_FLASH_SCK_PIN &pin_P0_19 + #define SPI_FLASH_CS_PIN &pin_P0_20 #endif #define DEFAULT_I2C_BUS_SCL (&pin_P0_11) diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index c8cba2877c..fbb9987c24 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -29,6 +29,7 @@ CIRCUITPY_BUSDEVICE = 0 MICROPY_PY_ASYNC_AWAIT = 0 SUPEROPT_GC = 0 +SUPEROPT_VM = 0 # Override optimization to keep binary small OPTIMIZATION_FLAGS = -Os diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 6bc05a7f08..52743d340f 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -3,8 +3,6 @@ USB_PID = 0xc051 USB_PRODUCT = "Simmel" USB_MANUFACTURER = "Betrusted" -CIRCUITPY_DEVICES="CDC,MSC,HID" - MCU_CHIP = nrf52833 # SPI_FLASH_FILESYSTEM = 1 @@ -31,6 +29,7 @@ CIRCUITPY_RTC = 1 CIRCUITPY_SDCARDIO = 0 CIRCUITPY_TOUCHIO = 0 CIRCUITPY_ULAB = 0 +CIRCUITPY_USB_CDC = 0 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WATCHDOG = 1 diff --git a/ports/nrf/common-hal/supervisor/Runtime.c b/ports/nrf/common-hal/supervisor/Runtime.c index ea663f897d..a24e86cdf0 100755 --- a/ports/nrf/common-hal/supervisor/Runtime.c +++ b/ports/nrf/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { return (bool) serial_bytes_available(); } diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 9560064fbc..83924ff795 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -11,6 +11,9 @@ INTERNAL_LIBM = 1 USB_SERIAL_NUMBER_LENGTH = 16 +# Number of USB endpoint pairs. +USB_NUM_EP = 8 + # All nRF ports have longints. LONGINT_IMPL = MPZ diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index b19e9267cc..2c2c0116fb 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -28,15 +28,15 @@ #include "supervisor/serial.h" -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_REPL_BLE #include "ble_uart.h" -#elif CIRCUITPY_SERIAL_UART +#elif CIRCUITPY_REPL_UART #include #include "nrf_gpio.h" #include "nrfx_uarte.h" #endif -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_REPL_BLE void serial_init(void) { ble_uart_init(); @@ -58,7 +58,7 @@ void serial_write(const char *text) { ble_uart_stdout_tx_str(text); } -#elif CIRCUITPY_SERIAL_UART +#elif CIRCUITPY_REPL_UART uint8_t serial_received_char; nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0); @@ -124,4 +124,4 @@ void serial_write_substring(const char *text, uint32_t len) { } } -#endif // CIRCUITPY_SERIAL_UART +#endif // CIRCUITPY_REPL_UART diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index e1169ce7d2..f5e65f2560 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -196,8 +196,10 @@ SRC_C += \ bindings/rp2pio/__init__.c \ common-hal/rp2pio/StateMachine.c \ common-hal/rp2pio/__init__.c \ + audio_dma.c \ background.c \ peripherals/pins.c \ + extmod/crypto-algorithms/sha256.c \ fatfs_port.c \ lib/libc/string0.c \ lib/mp-readline/readline.c \ diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c new file mode 100644 index 0000000000..96317984df --- /dev/null +++ b/ports/raspberrypi/audio_dma.c @@ -0,0 +1,383 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "audio_dma.h" + +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/WaveFile.h" +#include "supervisor/background_callback.h" + +#include "py/mpstate.h" +#include "py/runtime.h" + +#include "src/rp2_common/hardware_irq/include/hardware/irq.h" + +#if CIRCUITPY_AUDIOPWMIO || CIRCUITPY_AUDIOBUSIO + +#define AUDIO_DMA_CHANNEL_COUNT NUM_DMA_CHANNELS + +void audio_dma_convert_signed(audio_dma_t* dma, uint8_t* buffer, uint32_t buffer_length, + uint8_t** output_buffer, uint32_t* output_buffer_length) { + if (dma->first_buffer_free) { + *output_buffer = dma->first_buffer; + } else { + *output_buffer = dma->second_buffer; + } + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + if (dma->signed_to_unsigned || + dma->unsigned_to_signed || + dma->sample_spacing > 1 || + (dma->sample_resolution != dma->output_resolution)) { + *output_buffer_length = buffer_length / dma->sample_spacing; + uint32_t out_i = 0; + if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { + size_t shift = dma->output_resolution - dma->sample_resolution; + + for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + if (dma->signed_to_unsigned) { + ((uint16_t*) *output_buffer)[out_i] = ((uint16_t) ((int8_t*) buffer)[i] + 0x80) << shift; + } else if (dma->unsigned_to_signed) { + ((int16_t*) *output_buffer)[out_i] = ((int16_t) ((uint8_t*) buffer)[i] - 0x80) << shift; + } else { + ((uint16_t*) *output_buffer)[out_i] = ((uint16_t) ((uint8_t*) buffer)[i]) << shift; + } + out_i += 1; + } + } else if (dma->sample_resolution <= 8 && dma->output_resolution <= 8) { + for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + if (dma->signed_to_unsigned) { + ((uint8_t*) *output_buffer)[out_i] = ((int8_t*) buffer)[i] + 0x80; + } else if (dma->unsigned_to_signed) { + ((int8_t*) *output_buffer)[out_i] = ((uint8_t*) buffer)[i] - 0x80; + } else { + ((uint8_t*) *output_buffer)[out_i] = ((uint8_t*) buffer)[i]; + } + out_i += 1; + } + } else if (dma->sample_resolution > 8 && dma->output_resolution > 8) { + size_t shift = 16 - dma->output_resolution; + for (uint32_t i = 0; i < buffer_length / 2; i += dma->sample_spacing) { + if (dma->signed_to_unsigned) { + ((uint16_t*) *output_buffer)[out_i] = ((int16_t*) buffer)[i] + 0x8000; + } else if (dma->unsigned_to_signed) { + ((int16_t*) *output_buffer)[out_i] = ((uint16_t*) buffer)[i] - 0x8000; + } else { + ((uint16_t*) *output_buffer)[out_i] = ((uint16_t*) buffer)[i]; + } + if (dma->output_resolution < 16) { + if (dma->output_signed) { + ((int16_t*) *output_buffer)[out_i] = ((int16_t*) *output_buffer)[out_i] >> shift; + } else { + ((uint16_t*) *output_buffer)[out_i] = ((uint16_t*) *output_buffer)[out_i] >> shift; + } + } + out_i += 1; + } + } + } else { + *output_buffer = buffer; + *output_buffer_length = buffer_length; + } + #pragma GCC diagnostic pop + dma->first_buffer_free = !dma->first_buffer_free; +} + +void audio_dma_load_next_block(audio_dma_t* dma) { + uint8_t dma_channel = dma->channel[1]; + if (dma->first_channel_free) { + dma_channel = dma->channel[0]; + } + dma->first_channel_free = !dma->first_channel_free; + + uint8_t* output_buffer; + uint32_t output_buffer_length; + audioio_get_buffer_result_t get_buffer_result; + uint8_t* buffer; + uint32_t buffer_length; + get_buffer_result = audiosample_get_buffer(dma->sample, + dma->single_channel, dma->audio_channel, &buffer, &buffer_length); + + if (get_buffer_result == GET_BUFFER_ERROR) { + audio_dma_stop(dma); + return; + } + + audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length); + + // If we don't have an output buffer, save the pointer to first_buffer for use in the single + // buffer special case. + if (dma->first_buffer == NULL) { + dma->first_buffer = output_buffer; + } + + dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); + dma_channel_set_read_addr(dma_channel, output_buffer, false /* trigger */); + if (get_buffer_result == GET_BUFFER_DONE) { + if (dma->loop) { + audiosample_reset_buffer(dma->sample, dma->single_channel, dma->audio_channel); + } else { + // Set channel trigger to ourselves so we don't keep going. + dma_channel_hw_t* c = &dma_hw->ch[dma_channel]; + c->al1_ctrl = (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + } + } +} + +// Playback should be shutdown before calling this. +audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, + mp_obj_t sample, + bool loop, + bool single_channel, + uint8_t audio_channel, + bool output_signed, + uint8_t output_resolution, + uint32_t output_register_address, + uint8_t dma_trigger_source) { + // Use two DMA channels to because the DMA can't wrap to itself without the + // buffer being power of two aligned. + dma->channel[0] = dma_claim_unused_channel(false); + dma->channel[1] = dma_claim_unused_channel(false); + if (dma->channel[0] == NUM_DMA_CHANNELS || dma->channel[1] == NUM_DMA_CHANNELS) { + if (dma->channel[0] < NUM_DMA_CHANNELS) { + dma_channel_unclaim(dma->channel[0]); + } + return AUDIO_DMA_DMA_BUSY; + } + + dma->sample = sample; + dma->loop = loop; + dma->single_channel = single_channel; + dma->audio_channel = audio_channel; + dma->signed_to_unsigned = false; + dma->unsigned_to_signed = false; + dma->output_signed = output_signed; + dma->sample_spacing = 1; + dma->first_channel_free = true; + dma->output_resolution = output_resolution; + dma->sample_resolution = audiosample_bits_per_sample(sample); + audiosample_reset_buffer(sample, single_channel, audio_channel); + + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + audiosample_get_buffer_structure(sample, single_channel, &single_buffer, &samples_signed, + &max_buffer_length, &dma->sample_spacing); + + // Check to see if we have to scale the resolution up. + if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { + max_buffer_length *= 2; + } + if (output_signed != samples_signed || + dma->sample_spacing > 1 || + (dma->sample_resolution != dma->output_resolution)) { + max_buffer_length /= dma->sample_spacing; + dma->first_buffer = (uint8_t*) m_realloc(dma->first_buffer, max_buffer_length); + if (dma->first_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + + dma->first_buffer_free = true; + if (!single_buffer) { + dma->second_buffer = (uint8_t*) m_realloc(dma->second_buffer, max_buffer_length); + if (dma->second_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + } + + if (output_resolution > 8) { + dma->output_size = 2; + } else { + dma->output_size = 1; + } + // Transfer both channels at once. + if (!single_channel && audiosample_channel_count(sample) == 2) { + dma->output_size *= 2; + } + + enum dma_channel_transfer_size dma_size = DMA_SIZE_8; + if (dma->output_size == 2) { + dma_size = DMA_SIZE_16; + } else if (dma->output_size == 4) { + dma_size = DMA_SIZE_32; + } + + for (size_t i = 0; i < 2; i++) { + dma_channel_config c = dma_channel_get_default_config(dma->channel[i]); + channel_config_set_transfer_data_size(&c, dma_size); + channel_config_set_dreq(&c, dma_trigger_source); + channel_config_set_read_increment(&c, true); + channel_config_set_write_increment(&c, false); + // Chain to the other channel by default. + channel_config_set_chain_to(&c, dma->channel[(i + 1) % 2]); + dma_channel_set_config(dma->channel[i], &c, false /* trigger */); + dma_channel_set_write_addr(dma->channel[i], (void*) output_register_address, false /* trigger */); + } + + // We keep the audio_dma_t for internal use and the sample as a root pointer because it + // contains the audiodma structure. + MP_STATE_PORT(playing_audio)[dma->channel[0]] = dma; + MP_STATE_PORT(playing_audio)[dma->channel[1]] = dma; + + // Load the first two blocks up front. + audio_dma_load_next_block(dma); + if (!single_buffer) { + audio_dma_load_next_block(dma); + } + + // Special case the DMA for a single buffer. It's commonly used for a single wave length of sound + // and may be short. Therefore, we use DMA chaining to loop quickly without involving interrupts. + // On the RP2040 we chain by having a second DMA writing to the config registers of the first. + // Read and write addresses change with DMA so we need to reset the read address back to the + // start of the sample. + if (single_buffer) { + dma_channel_config c = dma_channel_get_default_config(dma->channel[1]); + channel_config_set_transfer_data_size(&c, DMA_SIZE_32); + channel_config_set_dreq(&c, 0x3f); // dma as fast as possible + channel_config_set_read_increment(&c, false); + channel_config_set_write_increment(&c, false); + channel_config_set_chain_to(&c, dma->channel[1]); // Chain to ourselves so we stop. + dma_channel_configure(dma->channel[1], &c, + &dma_hw->ch[dma->channel[0]].al3_read_addr_trig, // write address + &dma->first_buffer, // read address + 1, // transaction count + false); // trigger + } else { + // Enable our DMA channels on DMA0 to the CPU. This will wake us up when + // we're WFI. + dma_hw->inte0 |= (1 << dma->channel[0]) | (1 << dma->channel[1]); + irq_set_mask_enabled(1 << DMA_IRQ_0, true); + } + + dma_channel_start(dma->channel[0]); + + return AUDIO_DMA_OK; +} + +void audio_dma_stop(audio_dma_t* dma) { + // Disable our interrupts. + dma_hw->inte0 &= ~((1 << dma->channel[0]) | (1 << dma->channel[1])); + irq_set_mask_enabled(1 << DMA_IRQ_0, false); + + // Run any remaining audio tasks because we remove ourselves from + // playing_audio. + RUN_BACKGROUND_TASKS; + + for (size_t i = 0; i < 2; i++) { + size_t channel = dma->channel[i]; + + if (dma_channel_is_busy(channel)) { + dma_channel_abort(channel); + } + dma_channel_unclaim(channel); + MP_STATE_PORT(playing_audio)[channel] = NULL; + dma->channel[i] = NUM_DMA_CHANNELS; + } + + // Hold onto our buffers. +} + +// To pause we simply stop the DMA. It is the responsibility of the output peripheral +// to hold the previous value. +void audio_dma_pause(audio_dma_t* dma) { + dma_hw->ch[dma->channel[0]].al1_ctrl &= ~DMA_CH0_CTRL_TRIG_EN_BITS; + dma_hw->ch[dma->channel[1]].al1_ctrl &= ~DMA_CH0_CTRL_TRIG_EN_BITS; +} + +void audio_dma_resume(audio_dma_t* dma) { + // Always re-enable the non-busy channel first so it's ready to continue when the busy channel + // finishes and chains to it. (An interrupt could make the time between enables long.) + size_t first = 0; + size_t second = 1; + if (dma_channel_is_busy(dma->channel[0])) { + first = 1; + second = 0; + } + dma_hw->ch[dma->channel[first]].al1_ctrl |= DMA_CH0_CTRL_TRIG_EN_BITS; + dma_hw->ch[dma->channel[second]].al1_ctrl |= DMA_CH0_CTRL_TRIG_EN_BITS; +} + +bool audio_dma_get_paused(audio_dma_t* dma) { + if (dma->channel[0] >= AUDIO_DMA_CHANNEL_COUNT) { + return false; + } + uint32_t control = dma_hw->ch[dma->channel[0]].ctrl_trig; + + return (control & DMA_CH0_CTRL_TRIG_EN_BITS) == 0; +} + +void audio_dma_init(audio_dma_t* dma) { + dma->first_buffer = NULL; + dma->second_buffer = NULL; +} + +void audio_dma_deinit(audio_dma_t* dma) { + m_free(dma->first_buffer); + dma->first_buffer = NULL; + + m_free(dma->second_buffer); + dma->second_buffer = NULL; +} + +bool audio_dma_get_playing(audio_dma_t* dma) { + if (dma->channel[0] == NUM_DMA_CHANNELS) { + return false; + } + if (!dma_channel_is_busy(dma->channel[0]) && + !dma_channel_is_busy(dma->channel[1])) { + audio_dma_stop(dma); + return false; + } + + return true; +} + +// WARN(tannewt): DO NOT print from here, or anything it calls. Printing calls +// background tasks such as this and causes a stack overflow. +STATIC void dma_callback_fun(void *arg) { + audio_dma_t* dma = arg; + if (dma == NULL) { + return; + } + + audio_dma_load_next_block(dma); +} + +void isr_dma_0(void) { + for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) { + uint32_t mask = 1 << i; + if ((dma_hw->intr & mask) != 0 && MP_STATE_PORT(playing_audio)[i] != NULL) { + audio_dma_t* dma = MP_STATE_PORT(playing_audio)[i]; + background_callback_add(&dma->callback, dma_callback_fun, (void*)dma); + dma_hw->ints0 = mask; + } + } +} + +#endif diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h new file mode 100644 index 0000000000..1f739ff737 --- /dev/null +++ b/ports/raspberrypi/audio_dma.h @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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_RASPBERRYPI_AUDIO_DMA_OUT_H +#define MICROPY_INCLUDED_RASPBERRYPI_AUDIO_DMA_OUT_H + +#include "py/obj.h" +#include "supervisor/background_callback.h" + +#include "src/rp2_common/hardware_dma/include/hardware/dma.h" + +typedef struct { + mp_obj_t sample; + uint8_t channel[2]; + uint8_t audio_channel; + uint8_t output_size; + uint8_t sample_spacing; + bool loop; + bool single_channel; + bool signed_to_unsigned; + bool unsigned_to_signed; + bool output_signed; + bool first_channel_free; + bool first_buffer_free; + uint8_t output_resolution; // in bits + uint8_t sample_resolution; // in bits + uint8_t* first_buffer; + uint8_t* second_buffer; + background_callback_t callback; +} audio_dma_t; + +typedef enum { + AUDIO_DMA_OK, + AUDIO_DMA_DMA_BUSY, + AUDIO_DMA_MEMORY_ERROR, +} audio_dma_result; + + +void audio_dma_init(audio_dma_t* dma); +void audio_dma_deinit(audio_dma_t* dma); +void audio_dma_reset(void); + +// This sets everything up but doesn't start the timer. +// Sample is the python object for the sample to play. +// loop is true if we should loop the sample. +// single_channel is true if we only output a single channel. When false, all channels will be +// output. +// audio_channel is the index of the channel to dma. single_channel must be false in this case. +// output_signed is true if the dma'd data should be signed. False and it will be unsigned. +// output_register_address is the address to copy data to. +// dma_trigger_source is the DMA trigger source which cause another copy +audio_dma_result audio_dma_setup_playback(audio_dma_t* dma, + mp_obj_t sample, + bool loop, + bool single_channel, + uint8_t audio_channel, + bool output_signed, + uint8_t output_resolution, + uint32_t output_register_address, + uint8_t dma_trigger_source); + +void audio_dma_stop(audio_dma_t* dma); +bool audio_dma_get_playing(audio_dma_t* dma); +void audio_dma_pause(audio_dma_t* dma); +void audio_dma_resume(audio_dma_t* dma); +bool audio_dma_get_paused(audio_dma_t* dma); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_AUDIO_DMA_OUT_H diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index 0f6f84a565..34633949ed 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -189,7 +189,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n if (bufinfo.len % 2 != 0) { mp_raise_ValueError(translate("Program size invalid")); } - if (bufinfo.len > 32) { + if (bufinfo.len > 64) { mp_raise_ValueError(translate("Program too large")); } diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h index 6a2d063d79..f491a77698 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h @@ -12,3 +12,6 @@ // #define DEFAULT_UART_BUS_RX (&pin_PA11) // #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// Flash chip is GD25Q32 connected over QSPI +#define TOTAL_FLASH_SIZE (4 * 1024 * 1024) diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/board.c b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c new file mode 100644 index 0000000000..67486d4c23 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h new file mode 100644 index 0000000000..234be27c2c --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h @@ -0,0 +1,41 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Keybow 2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_SW0 (&pin_GPIO21) +#define MICROPY_HW_SW1 (&pin_GPIO20) +#define MICROPY_HW_SW2 (&pin_GPIO19) +#define MICROPY_HW_SW3 (&pin_GPIO18) +#define MICROPY_HW_SW4 (&pin_GPIO17) +#define MICROPY_HW_SW5 (&pin_GPIO16) +#define MICROPY_HW_SW6 (&pin_GPIO15) +#define MICROPY_HW_SW7 (&pin_GPIO14) +#define MICROPY_HW_SW8 (&pin_GPIO13) +#define MICROPY_HW_SW9 (&pin_GPIO12) +#define MICROPY_HW_SW10 (&pin_GPIO11) +#define MICROPY_HW_SW11 (&pin_GPIO10) +#define MICROPY_HW_SW12 (&pin_GPIO9) +#define MICROPY_HW_SW13 (&pin_GPIO8) +#define MICROPY_HW_SW14 (&pin_GPIO7) +#define MICROPY_HW_SW15 (&pin_GPIO6) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +#define MICROPY_HW_I2C_INT (&pin_GPIO3) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define TOTAL_FLASH_SIZE (2 * 1024 * 1024) + +// These pins are unconnected +#define IGNORE_PIN_GPIO2 1 +#define IGNORE_PIN_GPIO22 1 +#define IGNORE_PIN_GPIO24 1 +#define IGNORE_PIN_GPIO25 1 +#define IGNORE_PIN_GPIO26 1 +#define IGNORE_PIN_GPIO27 1 +#define IGNORE_PIN_GPIO28 1 +#define IGNORE_PIN_GPIO29 1 diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.mk new file mode 100644 index 0000000000..cf74294315 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x16D0 +USB_PID = 0x08C6 +USB_PRODUCT = "Keybow 2040" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +INTERNAL_FLASH_FILESYSTEM = 1 + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/pins.c b/ports/raspberrypi/boards/pimoroni_keybow2040/pins.c new file mode 100644 index 0000000000..c4cdb7b293 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/pins.c @@ -0,0 +1,36 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SW0), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SW1), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SW2), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SW3), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SW4), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SW5), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SW6), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SW7), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SW8), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SW9), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SW10), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SW11), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SW12), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SW13), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SW14), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SW15), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c new file mode 100644 index 0000000000..67486d4c23 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h new file mode 100644 index 0000000000..a1395f17d8 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h @@ -0,0 +1,49 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni PicoSystem" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_VBUS_DETECT (&pin_GPIO2) + +#define MICROPY_HW_LCD_RESET (&pin_GPIO4) +#define MICROPY_HW_LCD_CS (&pin_GPIO5) +#define MICROPY_HW_LCD_SCLK (&pin_GPIO6) +#define MICROPY_HW_LCD_MOSI (&pin_GPIO7) +#define MICROPY_HW_LCD_VSYNC (&pin_GPIO8) +#define MICROPY_HW_LCD_DS (&pin_GPIO9) + +#define MICROPY_HW_AUDIO (&pin_GPIO11) +#define MICROPY_HW_BACKLIGHT (&pin_GPIO12) +#define MICROPY_HW_VBUS_DETECT (&pin_GPIO2) + +#define MICROPY_HW_LED_G (&pin_GPIO13) +#define MICROPY_HW_LED_R (&pin_GPIO14) +#define MICROPY_HW_LED_B (&pin_GPIO15) + +#define MICROPY_HW_SW_Y (&pin_GPIO16) +#define MICROPY_HW_SW_X (&pin_GPIO17) +#define MICROPY_HW_SW_A (&pin_GPIO18) +#define MICROPY_HW_SW_B (&pin_GPIO19) + +#define MICROPY_HW_SW_DOWN (&pin_GPIO20) +#define MICROPY_HW_SW_RIGHT (&pin_GPIO21) +#define MICROPY_HW_SW_LEFT (&pin_GPIO22) +#define MICROPY_HW_SW_UP (&pin_GPIO23) + +#define MICROPY_HW_CHARGE_STAT (&pin_GPIO24) + +#define MICROPY_HW_BAT_SENSE (&pin_GPIO26) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define TOTAL_FLASH_SIZE (16 * 1024 * 1024) + +// These pins are unconnected +#define IGNORE_PIN_GPIO3 1 +#define IGNORE_PIN_GPIO10 1 +#define IGNORE_PIN_GPIO25 1 +#define IGNORE_PIN_GPIO27 1 +#define IGNORE_PIN_GPIO28 1 +#define IGNORE_PIN_GPIO29 1 diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk new file mode 100644 index 0000000000..c9d22549ba --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x16D0 +USB_PID = 0x08C8 +USB_PRODUCT = "PicoSystem" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +INTERNAL_FLASH_FILESYSTEM = 1 + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/pins.c b/ports/raspberrypi/boards/pimoroni_picosystem/pins.c new file mode 100644 index 0000000000..30aafacbad --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picosystem/pins.c @@ -0,0 +1,43 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_DETECT), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_RESET), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCLK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_LCD_VSYNC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_AUDIO), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_SW_Y), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SW_X), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SW_DOWN), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SW_RIGHT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SW_LEFT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SW_UP), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_CHARGE_STAT), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_BAT_SENSE), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/board.c b/ports/raspberrypi/boards/pimoroni_tiny2040/board.c new file mode 100644 index 0000000000..67486d4c23 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/board.c @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h new file mode 100644 index 0000000000..965dd0e042 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h @@ -0,0 +1,26 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Tiny 2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_R (&pin_GPIO18) +#define MICROPY_HW_LED_G (&pin_GPIO19) +#define MICROPY_HW_LED_B (&pin_GPIO20) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +#define TOTAL_FLASH_SIZE (8 * 1024 * 1024) + +// These pins are unconnected +#define IGNORE_PIN_GPIO8 1 +#define IGNORE_PIN_GPIO9 1 +#define IGNORE_PIN_GPIO10 1 +#define IGNORE_PIN_GPIO11 1 +#define IGNORE_PIN_GPIO12 1 +#define IGNORE_PIN_GPIO13 1 +#define IGNORE_PIN_GPIO14 1 +#define IGNORE_PIN_GPIO15 1 +#define IGNORE_PIN_GPIO16 1 +#define IGNORE_PIN_GPIO17 1 +#define IGNORE_PIN_GPIO21 1 +#define IGNORE_PIN_GPIO22 1 +#define IGNORE_PIN_GPIO24 1 +#define IGNORE_PIN_GPIO25 1 diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.mk new file mode 100644 index 0000000000..75fe36a29d --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x16D0 +USB_PID = 0x08C7 +USB_PRODUCT = "Tiny 2040" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +INTERNAL_FLASH_FILESYSTEM = 1 + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c b/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c new file mode 100644 index 0000000000..de79ee7320 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c @@ -0,0 +1,39 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/qtpy_rp2040/board.c b/ports/raspberrypi/boards/qtpy_rp2040/board.c new file mode 100644 index 0000000000..332145ab84 --- /dev/null +++ b/ports/raspberrypi/boards/qtpy_rp2040/board.c @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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 "supervisor/board.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" + +void board_init(void) { + common_hal_never_reset_pin(&pin_GPIO11); + gpio_init(11); + gpio_set_dir(11, GPIO_OUT); + gpio_put(11, true); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.h new file mode 100644 index 0000000000..3f47784572 --- /dev/null +++ b/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.h @@ -0,0 +1,17 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit QTPy RP2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO12) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO25) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO24) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO3) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4) + +// #define DEFAULT_UART_BUS_RX (&pin_PA11) +// #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// Flash chip is GD25Q32 connected over QSPI +#define TOTAL_FLASH_SIZE (4 * 1024 * 1024) diff --git a/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.mk new file mode 100644 index 0000000000..5e454e312e --- /dev/null +++ b/ports/raspberrypi/boards/qtpy_rp2040/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x80F8 +USB_PRODUCT = "QT Py RP2040" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/raspberrypi/boards/qtpy_rp2040/pins.c b/ports/raspberrypi/boards/qtpy_rp2040/pins.c new file mode 100644 index 0000000000..e0ebd0032b --- /dev/null +++ b/ports/raspberrypi/boards/qtpy_rp2040/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO11) }, + + + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO23) }, + + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + // { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h index 4b0a220287..a506fec49e 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h +++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h @@ -13,3 +13,6 @@ // #define DEFAULT_UART_BUS_RX (&pin_PA11) // #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// Flash chip is W25Q16JVUXIQ connected over QSPI +#define TOTAL_FLASH_SIZE (2 * 1024 * 1024) diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c new file mode 100644 index 0000000000..57605a1fb4 --- /dev/null +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -0,0 +1,235 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/audiopwmio/PWMAudioOut.h" + +#include +#include + +#include "extmod/vfs_fat.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/shared/tick.h" +#include "supervisor/shared/translate.h" + +#include "src/rp2040/hardware_structs/include/hardware/structs/dma.h" +#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" + +#define NUM_DMA_TIMERS 4 + +void audiopwmout_reset() { + for (size_t i = 0; i < NUM_DMA_TIMERS; i++) { + dma_hw->timer[i] = 0; + } +} + +// Caller validates that pins are free. +void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t* self, + const mcu_pin_obj_t* left_channel, const mcu_pin_obj_t* right_channel, uint16_t quiescent_value) { + if (left_channel != NULL && right_channel != NULL) { + if (pwm_gpio_to_slice_num(left_channel->number) != pwm_gpio_to_slice_num(right_channel->number)) { + mp_raise_ValueError(translate("Pins must share PWM slice")); + } + if (pwm_gpio_to_channel(left_channel->number) != 0) { + mp_raise_ValueError(translate("Stereo left must be on PWM channel A")); + } + if (pwm_gpio_to_channel(right_channel->number) != 1) { + mp_raise_ValueError(translate("Stereo right must be on PWM channel B")); + } + } + + // Typically pwmout doesn't let us change frequency with two objects on the + // same PWM slice. However, we have private access to it so we can do what + // we want. ;-) We mark ourselves variable only if we're a mono output to + // prevent other PWM use on the other channel. If stereo, we say fixed + // frequency so we can allocate with ourselves. + bool mono = right_channel == NULL; + + // We don't actually know our frequency yet so just pick one that shouldn't + // match anyone else. (We'll only know the frequency once we play something + // back.) + uint32_t frequency = 12500; + + // Make sure the PWMOut's are "deinited" by default. + self->left_pwm.pin = NULL; + self->right_pwm.pin = NULL; + + pwmout_result_t result = common_hal_pwmio_pwmout_construct(&self->left_pwm, + left_channel, 0, frequency, mono); + if (result == PWMOUT_OK && right_channel != NULL) { + result = common_hal_pwmio_pwmout_construct(&self->right_pwm, + right_channel, 0, frequency, false); + if (result != PWMOUT_OK) { + common_hal_pwmio_pwmout_deinit(&self->left_pwm); + } + } + if (result != PWMOUT_OK) { + mp_raise_RuntimeError(translate("All timers in use")); + } + + claim_pin(left_channel); + if (right_channel != NULL) { + claim_pin(right_channel); + } + + audio_dma_init(&self->dma); + + self->quiescent_value = quiescent_value; +} + +bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t* self) { + return common_hal_pwmio_pwmout_deinited(&self->left_pwm); +} + +void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t* self) { + if (common_hal_audiopwmio_pwmaudioout_deinited(self)) { + return; + } + if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) { + common_hal_audiopwmio_pwmaudioout_stop(self); + } + + // TODO: ramp the pwm down from quiescent value to 0 + common_hal_pwmio_pwmout_deinit(&self->left_pwm); + common_hal_pwmio_pwmout_deinit(&self->right_pwm); + + audio_dma_deinit(&self->dma); +} + +void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t* self, mp_obj_t sample, bool loop) { + if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) { + common_hal_audiopwmio_pwmaudioout_stop(self); + } + + // TODO: Share pacing timers based on frequency. + size_t pacing_timer = NUM_DMA_TIMERS; + for (size_t i = 0; i < NUM_DMA_TIMERS; i++) { + if (dma_hw->timer[i] == 0) { + pacing_timer = i; + } + break; + } + if (pacing_timer == NUM_DMA_TIMERS) { + mp_raise_RuntimeError(translate("No DMA pacing timer found")); + } + uint32_t tx_register = (uint32_t) &pwm_hw->slice[self->left_pwm.slice].cc; + if (common_hal_pwmio_pwmout_deinited(&self->right_pwm)) { + // Shift the destination if we are outputting to the second PWM channel. + tx_register += self->left_pwm.channel * sizeof(uint16_t); + } + + pwmio_pwmout_set_top(&self->left_pwm, 1023); + + audio_dma_result result = audio_dma_setup_playback( + &self->dma, + sample, + loop, + false, // single channel + 0, // audio channel + false, // output signed + 10, + (uint32_t) tx_register, // output register + 0x3b + pacing_timer); // data request line + + if (result == AUDIO_DMA_DMA_BUSY) { + // common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(translate("No DMA channel found")); + } else if (result == AUDIO_DMA_MEMORY_ERROR) { + // common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); + } + + // OK! We got all of the resources we need and dma is ready. + self->pacing_timer = pacing_timer; + + // Playback with two independent clocks. One is the sample rate which + // determines when we push a new sample to the PWM slice. The second is the + // PWM frequency itself. + + // Determine the DMA divisor. The RP2040 has four pacing timers we can use + // to trigger the DMA. Each has a 16 bit fractional divisor system clock * X / Y where X and Y + // are 16-bit. + + uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t system_clock = common_hal_mcu_processor_get_frequency(); + uint32_t best_numerator = 0; + uint32_t best_denominator = 0; + uint32_t best_error = system_clock; + + for (uint32_t denominator = 0xffff; denominator > 0; denominator--) { + uint32_t numerator = (denominator * sample_rate) / system_clock; + uint32_t remainder = (denominator * sample_rate) % system_clock; + if (remainder > (system_clock / 2)) { + numerator += 1; + remainder = system_clock - remainder; + } + if (remainder < best_error) { + best_denominator = denominator; + best_numerator = numerator; + best_error = remainder; + // Stop early if we can't do better. + if (remainder == 0) { + break; + } + } + } + + dma_hw->timer[pacing_timer] = best_numerator << 16 | best_denominator; +} + +void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t* self) { + dma_hw->timer[self->pacing_timer] = 0; + self->pacing_timer = NUM_DMA_TIMERS; + + audio_dma_stop(&self->dma); +} + +bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t* self) { + bool playing = audio_dma_get_playing(&self->dma); + if (!playing && self->pacing_timer < NUM_DMA_TIMERS) { + dma_hw->timer[self->pacing_timer] = 0; + self->pacing_timer = NUM_DMA_TIMERS; + } + return playing; +} + +void common_hal_audiopwmio_pwmaudioout_pause(audiopwmio_pwmaudioout_obj_t* self) { + audio_dma_pause(&self->dma); +} + +void common_hal_audiopwmio_pwmaudioout_resume(audiopwmio_pwmaudioout_obj_t* self) { + audio_dma_resume(&self->dma); +} + +bool common_hal_audiopwmio_pwmaudioout_get_paused(audiopwmio_pwmaudioout_obj_t* self) { + return audio_dma_get_paused(&self->dma); +} diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.h b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.h new file mode 100644 index 0000000000..2b43b8354d --- /dev/null +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_AUDIOPWMIO_PWMAUDIOOUT_H +#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_AUDIOPWMIO_PWMAUDIOOUT_H + +#include "common-hal/pwmio/PWMOut.h" + +#include "audio_dma.h" + +typedef struct { + mp_obj_base_t base; + pwmio_pwmout_obj_t left_pwm; + pwmio_pwmout_obj_t right_pwm; + audio_dma_t dma; + uint16_t quiescent_value; + uint8_t pacing_timer; +} audiopwmio_pwmaudioout_obj_t; + +void audiopwmout_reset(void); + +void audiopwmout_background(void); + +#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_AUDIOPWMIO_PWMAUDIOOUT_H diff --git a/ports/raspberrypi/common-hal/audiopwmio/__init__.c b/ports/raspberrypi/common-hal/audiopwmio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ports/raspberrypi/common-hal/neopixel_write/__init__.c b/ports/raspberrypi/common-hal/neopixel_write/__init__.c index 10462b5a33..561d438e2e 100644 --- a/ports/raspberrypi/common-hal/neopixel_write/__init__.c +++ b/ports/raspberrypi/common-hal/neopixel_write/__init__.c @@ -29,6 +29,7 @@ #include "bindings/rp2pio/StateMachine.h" #include "common-hal/rp2pio/StateMachine.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "supervisor/port.h" @@ -89,7 +90,11 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, // Use a private deinit of the state machine that doesn't reset the pin. rp2pio_statemachine_deinit(&state_machine, true); + + // Reset the pin and release it from the PIO gpio_init(digitalinout->pin->number); + common_hal_digitalio_digitalinout_switch_to_output((digitalio_digitalinout_obj_t*)digitalinout, false, DRIVE_MODE_PUSH_PULL); + // Update the next start. next_start_raw_ticks = port_get_raw_ticks(NULL) + 1; } diff --git a/ports/raspberrypi/common-hal/os/__init__.c b/ports/raspberrypi/common-hal/os/__init__.c index dcbd06e937..0df7653d39 100644 --- a/ports/raspberrypi/common-hal/os/__init__.c +++ b/ports/raspberrypi/common-hal/os/__init__.c @@ -30,6 +30,11 @@ #include "py/objtuple.h" #include "py/qstr.h" +#include "extmod/crypto-algorithms/sha256.h" + +#include "hardware/structs/rosc.h" + +#include STATIC const qstr os_uname_info_fields[] = { MP_QSTR_sysname, MP_QSTR_nodename, @@ -57,6 +62,64 @@ mp_obj_t common_hal_os_uname(void) { return (mp_obj_t)&os_uname_info_obj; } -bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) { - return false; +// NIST Special Publication 800-90B (draft) recommends several extractors, +// including the SHA hash family and states that if the amount of entropy input +// is twice the number of bits output from them, that output can be considered +// essentially fully random. If every RANDOM_SAFETY_MARGIN bits from +// `rosc_hw->randombit` have at least 1 bit of entropy, then this criterion is met. +// +// This works by seeding the `random_state` with plenty of random bits (SHA256 +// as entropy harvesting function), then using that state it as a counter input +// (SHA256 as a CSPRNG), re-seeding at least every 256 blocks (8kB). +// +// In practice, `PractRand` doesn't detect any gross problems with the output +// random numbers on samples of 1 to 8 megabytes, no matter the setting of +// RANDOM_SAFETY_MARGIN. (it does detect "unusual" results from time to time, +// as it will with any RNG) +#define RANDOM_SAFETY_MARGIN (4) + +static BYTE random_state[SHA256_BLOCK_SIZE]; +static void seed_random_bits(BYTE out[SHA256_BLOCK_SIZE]) { + CRYAL_SHA256_CTX context; + sha256_init(&context); + for (int i=0; i<2*RANDOM_SAFETY_MARGIN; i++) { + for(int j=0; jrandombit & 1; + for(int k=0; k<8; k++) { + out[j] = (out[j] << 1) ^ (rosc_hw->randombit & 1); + } + } + sha256_update(&context, out, SHA256_BLOCK_SIZE); + } + sha256_final(&context, out); +} + +static void get_random_bits(BYTE out[SHA256_BLOCK_SIZE]) { + if (!random_state[0]++) { + seed_random_bits(random_state); + } + CRYAL_SHA256_CTX context; + sha256_init(&context); + sha256_update(&context, random_state, SHA256_BLOCK_SIZE); + sha256_final(&context, out); +} + +bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) { +#define ROSC_POWER_SAVE (1) // assume ROSC is not necessarily active all the time +#if ROSC_POWER_SAVE + uint32_t old_rosc_ctrl = rosc_hw->ctrl; + rosc_hw->ctrl = (old_rosc_ctrl & ~ROSC_CTRL_ENABLE_BITS) | (ROSC_CTRL_ENABLE_VALUE_ENABLE << 12); +#endif + while (length) { + size_t n = MIN(length, SHA256_BLOCK_SIZE); + BYTE sha_buf[SHA256_BLOCK_SIZE]; + get_random_bits(sha_buf); + memcpy(buffer, sha_buf, n); + buffer += n; + length -= n; + } +#if ROSC_POWER_SAVE + rosc_hw->ctrl = old_rosc_ctrl; +#endif + return true; } diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 567ec5ef54..00b461880c 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -39,12 +39,24 @@ #include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" uint32_t target_slice_frequencies[NUM_PWM_SLICES]; -uint32_t slice_fixed_frequency; +uint32_t slice_variable_frequency; #define CHANNELS_PER_SLICE 2 static uint32_t channel_use; static uint32_t never_reset_channel; +// Per the RP2040 datasheet: +// +// "A CC value of 0 will produce a 0% output, i.e. the output signal +// is always low. A CC value of TOP + 1 (i.e. equal to the period, in +// non-phase-correct mode) will produce a 100% output. For example, if +// TOP is programmed to 254, the counter will have a period of 255 +// cycles, and CC values in the range of 0 to 255 inclusive will +// produce duty cycles in the range 0% to 100% inclusive." +// +// So 65534 should be the maximum top value, and we'll set CC to be TOP+1 as appropriate. +#define MAX_TOP 65534 + static uint32_t _mask(uint8_t slice, uint8_t channel) { return 1 << (slice * CHANNELS_PER_SLICE + channel); } @@ -76,7 +88,7 @@ void pwmout_reset(void) { } pwm_set_enabled(slice, false); target_slice_frequencies[slice] = 0; - slice_fixed_frequency &= ~(1 << slice); + slice_variable_frequency &= ~(1 << slice); } } @@ -107,8 +119,8 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self, if (variable_frequency) { return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; } - // If the other user wants to change frequency then we can't share either. - if ((slice_fixed_frequency & (1 << slice)) != 0) { + // If the other user wants a variable frequency then we can't share either. + if ((slice_variable_frequency & (1 << slice)) != 0) { return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; } // If we're both fixed frequency but we don't match target frequencies then we can't share. @@ -118,9 +130,10 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self, } self->slice = slice; self->channel = channel; + channel_use |= channel_use_mask; - if (!variable_frequency) { - slice_fixed_frequency |= 1 << slice; + if (variable_frequency) { + slice_variable_frequency |= 1 << slice; } if (target_slice_frequencies[slice] != frequency) { @@ -153,7 +166,7 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) { uint32_t slice_mask = ((1 << CHANNELS_PER_SLICE) - 1) << (self->slice * CHANNELS_PER_SLICE + self->channel); if ((channel_use & slice_mask) == 0) { target_slice_frequencies[self->slice] = 0; - slice_fixed_frequency &= ~(1 << self->slice); + slice_variable_frequency &= ~(1 << self->slice); pwm_set_enabled(self->slice, false); } @@ -163,14 +176,30 @@ void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) { extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t* self, uint16_t duty) { self->duty_cycle = duty; - uint16_t actual_duty = duty * self->top / ((1 << 16) - 1); - pwm_set_chan_level(self->slice, self->channel, actual_duty); + // Do arithmetic in 32 bits to prevent overflow. + uint16_t compare_count; + if (duty == 65535) { + // Ensure that 100% duty cycle is 100% full on and not rounded down, + // but do MIN() to keep value in range, just in case. + compare_count = MIN(UINT16_MAX, (uint32_t) self->top + 1); + } else { + compare_count= ((uint32_t) duty * self->top + MAX_TOP / 2) / MAX_TOP; + } + // compare_count is the CC register value, which should be TOP+1 for 100% duty cycle. + pwm_set_chan_level(self->slice, self->channel, compare_count); } uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t* self) { return self->duty_cycle; } +void pwmio_pwmout_set_top(pwmio_pwmout_obj_t* self, uint16_t top) { + self->actual_frequency = common_hal_mcu_processor_get_frequency() / top; + self->top = top; + pwm_set_clkdiv_int_frac(self->slice, 1, 0); + pwm_set_wrap(self->slice, self->top); +} + void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self, uint32_t frequency) { if (frequency == 0 || frequency > (common_hal_mcu_processor_get_frequency() / 2)) { mp_raise_ValueError(translate("Invalid PWM frequency")); @@ -179,7 +208,7 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self, uint32_t fr target_slice_frequencies[self->slice] = frequency; // For low frequencies use the divider to give us full resolution duty_cycle. - if (frequency < (common_hal_mcu_processor_get_frequency() / (1 << 16))) { + if (frequency <= (common_hal_mcu_processor_get_frequency() / (1 << 16))) { // Compute the divisor. It's an 8 bit integer and 4 bit fraction. Therefore, // we compute everything * 16 for the fractional part. // This is 1 << 12 because 4 bits are the * 16. @@ -193,16 +222,17 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self, uint32_t fr if (div16 >= (1 << 12)) { div16 = (1 << 12) - 1; } - self->actual_frequency = frequency16 / div16; - self->top = 1 << 16; + self->actual_frequency = (frequency16 + (div16 / 2)) / div16; + self->top = MAX_TOP; pwm_set_clkdiv_int_frac(self->slice, div16 / 16, div16 % 16); - pwm_set_wrap(self->slice, self->top - 1); + pwm_set_wrap(self->slice, self->top); } else { uint32_t top = common_hal_mcu_processor_get_frequency() / frequency; self->actual_frequency = common_hal_mcu_processor_get_frequency() / top; - self->top = top; + self->top = MIN(MAX_TOP, top); pwm_set_clkdiv_int_frac(self->slice, 1, 0); - pwm_set_wrap(self->slice, self->top - 1); + // Set TOP register. For 100% duty cycle, CC must be set to TOP+1. + pwm_set_wrap(self->slice, self->top); } common_hal_pwmio_pwmout_set_duty_cycle(self, self->duty_cycle); } diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.h b/ports/raspberrypi/common-hal/pwmio/PWMOut.h index 50f84777b5..0070e188b5 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.h +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.h @@ -39,9 +39,11 @@ typedef struct { bool variable_frequency; uint16_t duty_cycle; uint32_t actual_frequency; - uint32_t top; + uint16_t top; } pwmio_pwmout_obj_t; void pwmout_reset(void); +// Private API for AudioPWMOut. +void pwmio_pwmout_set_top(pwmio_pwmout_obj_t* self, uint16_t top); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index 6510410b0e..90c48130e1 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -546,15 +546,23 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, size_t tx_remaining = out_len; while (rx_remaining || tx_remaining) { - if (tx_remaining && !pio_sm_is_tx_fifo_full(self->pio, self->state_machine)) { - *tx_destination = *data_out; - data_out++; - --tx_remaining; - } - if (rx_remaining && !pio_sm_is_rx_fifo_empty(self->pio, self->state_machine)) { - *data_in = (uint8_t) *rx_source; - data_in++; - --rx_remaining; + for (int i=0; i<32; i++) { + bool did_transfer = false; + if (tx_remaining && !pio_sm_is_tx_fifo_full(self->pio, self->state_machine)) { + *tx_destination = *data_out; + data_out++; + --tx_remaining; + did_transfer = true; + } + if (rx_remaining && !pio_sm_is_rx_fifo_empty(self->pio, self->state_machine)) { + *data_in = (uint8_t) *rx_source; + data_in++; + --rx_remaining; + did_transfer = true; + } + if (!did_transfer) { + break; + } } RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { diff --git a/ports/raspberrypi/common-hal/supervisor/Runtime.c b/ports/raspberrypi/common-hal/supervisor/Runtime.c index 6be38f216a..974f26cec1 100755 --- a/ports/raspberrypi/common-hal/supervisor/Runtime.c +++ b/ports/raspberrypi/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { return (bool) serial_bytes_available(); } diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index 77d1ff0805..e0d98579dd 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -27,6 +27,8 @@ #ifndef __INCLUDED_MPCONFIGPORT_H #define __INCLUDED_MPCONFIGPORT_H +#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" + #define MICROPY_PY_SYS_PLATFORM "RP2040" #define CIRCUITPY_INTERNAL_NVM_SIZE 0 @@ -41,6 +43,7 @@ #include "py/circuitpy_mpconfig.h" #define MICROPY_PORT_ROOT_POINTERS \ + mp_obj_t playing_audio[NUM_DMA_CHANNELS]; \ CIRCUITPY_COMMON_ROOT_POINTERS; #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 8681e29949..ab85c59f9a 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -24,11 +24,10 @@ CIRCUITPY_NEOPIXEL_WRITE = 0 endif CIRCUITPY_FULL_BUILD = 1 +CIRCUITPY_BITOPS = 1 CIRCUITPY_PWMIO = 1 # Things that need to be implemented. -CIRCUITPY_AUDIOBUSIO = 0 # Use PIO interally for I2S -CIRCUITPY_AUDIOMP3 = 0 CIRCUITPY_COUNTIO = 0 # Use PWM interally CIRCUITPY_FREQUENCYIO = 0 # Use PWM interally CIRCUITPY_I2CPERIPHERAL = 0 @@ -37,11 +36,19 @@ CIRCUITPY_PULSEIO = 0 # Use PIO interally CIRCUITPY_ROTARYIO = 0 # Use PIO interally CIRCUITPY_WATCHDOG = 1 -# Things that are unsupported by the hardware. +# Audio via PWM CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_AUDIOBUSIO ?= 0 # add this later +CIRCUITPY_AUDIOCORE ?= 1 +CIRCUITPY_AUDIOPWMIO ?= 1 + +# These libraries require Cortex M4+ for fancy math instructions. +CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_AUDIOMP3 ?= 0 INTERNAL_LIBM = 1 USB_SERIAL_NUMBER_LENGTH = 16 +# Number of USB endpoint pairs. USB_NUM_EP = 8 diff --git a/ports/raspberrypi/supervisor/internal_flash.c b/ports/raspberrypi/supervisor/internal_flash.c index d333830de9..e8ee5cf1a6 100644 --- a/ports/raspberrypi/supervisor/internal_flash.c +++ b/ports/raspberrypi/supervisor/internal_flash.c @@ -44,10 +44,7 @@ #include "src/rp2_common/hardware_flash/include/hardware/flash.h" #include "src/common/pico_binary_info/include/pico/binary_info.h" -#define RESERVED_FLASH 1 * 1024 * 1024 - -// TODO: Parameterize flash size based on the configured flash. -#define TOTAL_FLASH_SIZE 2 * 1024 * 1024 +#define RESERVED_FLASH (1 * 1024 * 1024) // TODO: Split the caching out of supervisor/shared/external_flash so we can use it. #define SECTOR_SIZE 4096 diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 7c503514ab..36d2e8275c 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -32,6 +32,7 @@ #include "bindings/rp2pio/StateMachine.h" #include "genhdr/mpversion.h" +#include "shared-bindings/audiopwmio/PWMAudioOut.h" #include "shared-bindings/busio/I2C.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/microcontroller/__init__.h" @@ -108,6 +109,10 @@ void reset_port(void) { rtc_reset(); #endif + #if CIRCUITPY_AUDIOPWMIO + audiopwmout_reset(); + #endif + reset_all_pins(); } diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk index 81c3772e72..6d45769f2b 100644 --- a/ports/stm/boards/espruino_pico/mpconfigboard.mk +++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk @@ -21,5 +21,6 @@ LD_FILE = boards/STM32F401xd_fs.ld # meantime CIRCUITPY_ULAB = 0 CIRCUITPY_BUSDEVICE = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 SUPEROPT_GC = 0 diff --git a/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.mk b/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.mk index c99eb1a008..28874f9c6c 100644 --- a/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.mk +++ b/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.mk @@ -16,5 +16,3 @@ MCU_PACKAGE = LQFP144 LD_COMMON = boards/common_default.ld LD_FILE = boards/STM32F412_fs.ld - -CIRCUITPY_USB_HID = 1 diff --git a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk index a2e1da1011..4436f04b77 100644 --- a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk +++ b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk @@ -2,7 +2,9 @@ USB_VID = 0x239A USB_PID = 0x8071 USB_PRODUCT = "Thunderpack STM32F411" USB_MANUFACTURER = "Jeremy Gillick" -USB_DEVICES = "CDC,MSC" + +# Turn off HID devices +CIRCUITPY_USB_HID = 0 LONGINT_IMPL = NONE diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index de69da211a..7726b5e87f 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -61,6 +61,7 @@ STATIC bool never_reset_i2c[MAX_I2C]; #define ALL_CLOCKS 0xFF STATIC void i2c_clock_enable(uint8_t mask); STATIC void i2c_clock_disable(uint8_t mask); +STATIC void i2c_assign_irq(busio_i2c_obj_t *self, I2C_TypeDef * I2Cx); void i2c_reset(void) { uint16_t never_reset_mask = 0x00; @@ -136,6 +137,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, i2c_clock_enable(1 << (self->sda->periph_index - 1)); reserved_i2c[self->sda->periph_index - 1] = true; + // Create root pointer and assign IRQ + MP_STATE_PORT(cpy_i2c_obj_all)[self->sda->periph_index - 1] = self; + i2c_assign_irq(self, I2Cx); + // Handle the HAL handle differences #if (CPY_STM32H7 || CPY_STM32F7) if (frequency == 400000) { @@ -163,6 +168,13 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, } common_hal_mcu_pin_claim(sda); common_hal_mcu_pin_claim(scl); + + self->frame_in_prog = false; + + //start the receive interrupt chain + HAL_NVIC_DisableIRQ(self->irq); //prevent handle lock contention + HAL_NVIC_SetPriority(self->irq, 1, 0); + HAL_NVIC_EnableIRQ(self->irq); } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { @@ -229,15 +241,46 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { - HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), + HAL_StatusTypeDef result; + if (!transmit_stop_bit) { + uint32_t xfer_opt; + if (!self->frame_in_prog) { + xfer_opt = I2C_FIRST_FRAME; + } else { + // handle rare possibility of multiple restart writes in a row + xfer_opt = I2C_NEXT_FRAME; + } + result = HAL_I2C_Master_Seq_Transmit_IT(&(self->handle), + (uint16_t)(addr << 1), (uint8_t *)data, + (uint16_t)len, xfer_opt); + while (HAL_I2C_GetState(&(self->handle)) != HAL_I2C_STATE_READY) + { + RUN_BACKGROUND_TASKS; + } + self->frame_in_prog = true; + } else { + result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, (uint16_t)len, 500); + } return result == HAL_OK ? 0 : MP_EIO; } uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) + if (!self->frame_in_prog) { + return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) == HAL_OK ? 0 : MP_EIO; + } else { + HAL_StatusTypeDef result = HAL_I2C_Master_Seq_Receive_IT(&(self->handle), + (uint16_t)(addr << 1), (uint8_t *)data, + (uint16_t)len, I2C_LAST_FRAME); + while (HAL_I2C_GetState(&(self->handle)) != HAL_I2C_STATE_READY) + { + RUN_BACKGROUND_TASKS; + } + self->frame_in_prog = false; + return result; + } } STATIC void i2c_clock_enable(uint8_t mask) { @@ -294,3 +337,48 @@ STATIC void i2c_clock_disable(uint8_t mask) { } #endif } + +STATIC void i2c_assign_irq(busio_i2c_obj_t *self, I2C_TypeDef * I2Cx) { + #ifdef I2C1 + if (I2Cx == I2C1) { + self->irq = I2C1_EV_IRQn; + } + #endif + #ifdef I2C2 + if (I2Cx == I2C2) { + self->irq = I2C2_EV_IRQn; + } + #endif + #ifdef I2C3 + if (I2Cx == I2C3) { + self->irq = I2C3_EV_IRQn; + } + #endif + #ifdef I2C4 + if (I2Cx == I2C4) { + self->irq = I2C4_EV_IRQn; + } + #endif +} + +STATIC void call_hal_irq(int i2c_num) { + //Create casted context pointer + busio_i2c_obj_t * context = (busio_i2c_obj_t*)MP_STATE_PORT(cpy_i2c_obj_all)[i2c_num - 1]; + if (context != NULL) { + HAL_NVIC_ClearPendingIRQ(context->irq); + HAL_I2C_EV_IRQHandler(&context->handle); + } +} + +void I2C1_EV_IRQHandler(void) { + call_hal_irq(1); +} +void I2C2_EV_IRQHandler(void) { + call_hal_irq(2); +} +void I2C3_EV_IRQHandler(void) { + call_hal_irq(3); +} +void I2C4_EV_IRQHandler(void) { + call_hal_irq(4); +} diff --git a/ports/stm/common-hal/busio/I2C.h b/ports/stm/common-hal/busio/I2C.h index 5ca2854eb8..687e6a8c4d 100644 --- a/ports/stm/common-hal/busio/I2C.h +++ b/ports/stm/common-hal/busio/I2C.h @@ -37,6 +37,8 @@ typedef struct { mp_obj_base_t base; I2C_HandleTypeDef handle; + IRQn_Type irq; + bool frame_in_prog; bool has_lock; const mcu_periph_obj_t *scl; const mcu_periph_obj_t *sda; diff --git a/ports/stm/common-hal/supervisor/Runtime.c b/ports/stm/common-hal/supervisor/Runtime.c index ea663f897d..974f26cec1 100755 --- a/ports/stm/common-hal/supervisor/Runtime.c +++ b/ports/stm/common-hal/supervisor/Runtime.c @@ -28,10 +28,10 @@ #include "shared-bindings/supervisor/Runtime.h" #include "supervisor/serial.h" -bool common_hal_get_serial_connected(void) { +bool common_hal_supervisor_runtime_get_serial_connected(void) { return (bool) serial_connected(); } -bool common_hal_get_serial_bytes_available(void) { - return (bool) serial_bytes_available(); +bool common_hal_supervisor_runtime_get_serial_bytes_available(void) { + return (bool) serial_bytes_available(); } diff --git a/ports/stm/mpconfigport.h b/ports/stm/mpconfigport.h index 7cdab04f62..3f64e6565b 100644 --- a/ports/stm/mpconfigport.h +++ b/ports/stm/mpconfigport.h @@ -52,10 +52,14 @@ extern uint8_t _ld_default_stack_size; #define BOARD_NO_VBUS_SENSE (0) #endif -#define MAX_UART 10 //how many UART are implemented +// Peripheral implementation counts +#define MAX_UART 10 +#define MAX_I2C 4 +#define MAX_SPI 6 #define MICROPY_PORT_ROOT_POINTERS \ void *cpy_uart_obj_all[MAX_UART]; \ + void *cpy_i2c_obj_all[MAX_I2C]; \ CIRCUITPY_COMMON_ROOT_POINTERS #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk index bcecaa5170..fe257fc505 100644 --- a/ports/stm/mpconfigport.mk +++ b/ports/stm/mpconfigport.mk @@ -8,6 +8,7 @@ ifeq ($(MCU_VARIANT),STM32F405xx) CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_RGBMATRIX ?= 1 CIRCUITPY_SDIOIO ?= 1 + # Number of USB endpoint pairs. USB_NUM_EP = 4 endif @@ -23,6 +24,8 @@ ifeq ($(MCU_SERIES),F4) CIRCUITPY_RTC ?= 0 CIRCUITPY_USB_MIDI ?= 0 CIRCUITPY_USB_HID ?= 0 + + USB_NUM_EP = 4 endif ifeq ($(MCU_SERIES),H7) @@ -40,6 +43,8 @@ ifeq ($(MCU_SERIES),H7) CIRCUITPY_RTC ?= 0 CIRCUITPY_USB_HID ?= 0 CIRCUITPY_USB_MIDI ?= 0 + + USB_NUM_EP = 9 endif ifeq ($(MCU_SERIES),F7) @@ -56,4 +61,6 @@ ifeq ($(MCU_SERIES),F7) CIRCUITPY_RTC ?= 0 CIRCUITPY_USB_HID ?= 0 CIRCUITPY_USB_MIDI ?= 0 + + USB_NUM_EP = 6 endif diff --git a/py/builtinevex.c b/py/builtinevex.c index ade12d39d0..cff57c4131 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -132,17 +132,18 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i } #endif - size_t str_len; - const char *str = mp_obj_str_get_data(args[0], &str_len); + // Extract the source code. + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); // create the lexer // MP_PARSE_SINGLE_INPUT is used to indicate a file input mp_lexer_t *lex; if (MICROPY_PY_BUILTINS_EXECFILE && parse_input_kind == MP_PARSE_SINGLE_INPUT) { - lex = mp_lexer_new_from_file(str); + lex = mp_lexer_new_from_file(bufinfo.buf); parse_input_kind = MP_PARSE_FILE_INPUT; } else { - lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, str, str_len, 0); + lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, bufinfo.buf, bufinfo.len, 0); } return mp_parse_compile_execute(lex, parse_input_kind, globals, locals); diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index f907bf7ae6..943c99f937 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -139,6 +139,9 @@ endif ifeq ($(CIRCUITPY_BITBANG_APA102),1) SRC_PATTERNS += bitbangio/SPI% endif +ifeq ($(CIRCUITPY_BITOPS),1) +SRC_PATTERNS += bitops/% +endif ifeq ($(CIRCUITPY_BLEIO),1) SRC_PATTERNS += _bleio/% endif @@ -286,6 +289,9 @@ endif ifeq ($(CIRCUITPY_UHEAP),1) SRC_PATTERNS += uheap/% endif +ifeq ($(CIRCUITPY_USB_CDC),1) +SRC_PATTERNS += usb_cdc/% +endif ifeq ($(CIRCUITPY_USB_HID),1) SRC_PATTERNS += usb_hid/% endif @@ -466,6 +472,7 @@ SRC_SHARED_MODULE_ALL = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ bitbangio/__init__.c \ + bitops/__init__.c \ board/__init__.c \ adafruit_bus_device/__init__.c \ adafruit_bus_device/I2CDevice.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index ee23c71569..cbe668289b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -306,6 +306,14 @@ extern const struct _mp_obj_module_t bitbangio_module; #define BITBANGIO_MODULE #endif +#if CIRCUITPY_BITOPS +extern const struct _mp_obj_module_t bitops_module; +#define BITOPS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bitops),(mp_obj_t)&bitops_module }, +#else +#define BITOPS_MODULE +#endif + + #if CIRCUITPY_BLEIO #define BLEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__bleio), (mp_obj_t)&bleio_module }, extern const struct _mp_obj_module_t bleio_module; @@ -736,6 +744,13 @@ extern const struct _mp_obj_module_t uheap_module; #define UHEAP_MODULE #endif +#if CIRCUITPY_USB_CDC +extern const struct _mp_obj_module_t usb_cdc_module; +#define USB_CDC_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_cdc),(mp_obj_t)&usb_cdc_module }, +#else +#define USB_CDC_MODULE +#endif + #if CIRCUITPY_USB_HID extern const struct _mp_obj_module_t usb_hid_module; #define USB_HID_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, @@ -820,6 +835,7 @@ extern const struct _mp_obj_module_t msgpack_module; AUDIOPWMIO_MODULE \ BINASCII_MODULE \ BITBANGIO_MODULE \ + BITOPS_MODULE \ BLEIO_MODULE \ BOARD_MODULE \ BUSDEVICE_MODULE \ @@ -875,6 +891,7 @@ extern const struct _mp_obj_module_t msgpack_module; SUPERVISOR_MODULE \ TOUCHIO_MODULE \ UHEAP_MODULE \ + USB_CDC_MODULE \ USB_HID_MODULE \ USB_MIDI_MODULE \ USTACK_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index d9c7c0d331..ad63866360 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -89,9 +89,15 @@ CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3) CIRCUITPY_BINASCII ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_BINASCII=$(CIRCUITPY_BINASCII) +CIRCUITPY_BITBANG_APA102 ?= 0 +CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102) + CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO) +CIRCUITPY_BITOPS ?= 0 +CFLAGS += -DCIRCUITPY_BITOPS=$(CIRCUITPY_BITOPS) + # _bleio can be supported on most any board via HCI CIRCUITPY_BLEIO_HCI ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_BLEIO_HCI=$(CIRCUITPY_BLEIO_HCI) @@ -100,6 +106,9 @@ CFLAGS += -DCIRCUITPY_BLEIO_HCI=$(CIRCUITPY_BLEIO_HCI) CIRCUITPY_BLEIO ?= $(CIRCUITPY_BLEIO_HCI) CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO) +CIRCUITPY_BLE_FILE_SERVICE ?= 0 +CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE) + CIRCUITPY_BOARD ?= 1 CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD) @@ -127,6 +136,13 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +CIRCUITPY_DUALBANK ?= 0 +CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) + +# Enabled micropython.native decorator (experimental) +CIRCUITPY_ENABLE_MPY_NATIVE ?= 0 +CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE) + CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) @@ -179,6 +195,9 @@ CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR) CIRCUITPY_MICROCONTROLLER ?= 1 CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER) +CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK) + CIRCUITPY_NEOPIXEL_WRITE ?= 1 CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE) @@ -192,8 +211,8 @@ CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) CIRCUITPY_OS ?= 1 CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) -CIRCUITPY_DUALBANK ?= 0 -CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) +CIRCUITPY_PEW ?= 0 +CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW) CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) @@ -216,6 +235,20 @@ CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM) CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE) +CIRCUITPY_REPL_BLE ?= 0 +CFLAGS += -DCIRCUITPY_REPL_BLE=$(CIRCUITPY_REPL_BLE) + +CIRCUITPY_REPL_UART ?= 0 +CFLAGS += -DCIRCUITPY_REPL_UART=$(CIRCUITPY_REPL_UART) + +CIRCUITPY_REPL_USB ?= 1 +CFLAGS += -DCIRCUITPY_REPL_USB=$(CIRCUITPY_REPL_USB) + +# Should busio.I2C() check for pullups? +# Some boards in combination with certain peripherals may not want this. +CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1 +CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS) + # CIRCUITPY_RP2PIO is handled in the raspberrypi tree. # Only for rp2 chips. # Assume not a rp2 build. @@ -282,46 +315,54 @@ CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO) CIRCUITPY_UHEAP ?= 0 CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP) +# Secondary CDC is usually available if there are at least 8 endpoints. +CIRCUITPY_USB_CDC ?= $(shell expr $(USB_NUM_EP) '>=' 8) +CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC) + CIRCUITPY_USB_HID ?= 1 CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID) +CIRCUITPY_USB_HID_CONSUMER ?= 1 +CFLAGS += -DCIRCUITPY_USB_HID_CONSUMER=$(CIRCUITPY_USB_HID_CONSUMER) + +CIRCUITPY_USB_HID_DIGITIZER ?= 0 +CFLAGS += -DCIRCUITPY_USB_HID_DIGITIZER=$(CIRCUITPY_USB_HID_DIGITIZER) + +CIRCUITPY_USB_HID_GAMEPAD ?= 1 +CFLAGS += -DCIRCUITPY_USB_HID_GAMEPAD=$(CIRCUITPY_USB_HID_GAMEPAD) + +CIRCUITPY_USB_HID_KEYBOARD ?= 1 +CFLAGS += -DCIRCUITPY_USB_HID_KEYBOARD=$(CIRCUITPY_USB_HID_KEYBOARD) + +CIRCUITPY_USB_HID_MOUSE ?= 1 +CFLAGS += -DCIRCUITPY_USB_HID_MOUSE=$(CIRCUITPY_USB_HID_MOUSE) + +CIRCUITPY_USB_HID_SYS_CONTROL ?= 0 +CFLAGS += -DCIRCUITPY_USB_HID_SYS_CONTROL=$(CIRCUITPY_USB_HID_SYS_CONTROL) + +CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD ?= 0 +CFLAGS += -DCIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD=$(CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD) + CIRCUITPY_USB_MIDI ?= 1 CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) +CIRCUITPY_USB_MSC ?= 1 +CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC) + # Defaulting this to OFF initially because it has only been tested on a # limited number of platforms, and the other platforms do not have this # setting in their mpconfigport.mk and/or mpconfigboard.mk files yet. CIRCUITPY_USB_VENDOR ?= 0 CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR) -CIRCUITPY_PEW ?= 0 -CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW) +ifndef USB_NUM_EP +$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined") +endif # For debugging. CIRCUITPY_USTACK ?= 0 CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK) -# Non-module conditionals - -CIRCUITPY_BITBANG_APA102 ?= 0 -CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102) - -# Should busio.I2C() check for pullups? -# Some boards in combination with certain peripherals may not want this. -CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1 -CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS) - -# REPL over BLE -CIRCUITPY_SERIAL_BLE ?= 0 -CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE) - -CIRCUITPY_BLE_FILE_SERVICE ?= 0 -CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE) - -# REPL over UART -CIRCUITPY_SERIAL_UART ?= 0 -CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART) - # ulab numerics library CIRCUITPY_ULAB ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ULAB=$(CIRCUITPY_ULAB) @@ -332,10 +373,3 @@ CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG) CIRCUITPY_WIFI ?= 0 CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI) - -# Enabled micropython.native decorator (experimental) -CIRCUITPY_ENABLE_MPY_NATIVE ?= 0 -CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE) - -CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD) -CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK) diff --git a/py/obj.h b/py/obj.h index 066562cc43..c3ab63b5cc 100644 --- a/py/obj.h +++ b/py/obj.h @@ -684,6 +684,7 @@ mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); mp_obj_t mp_obj_new_int_from_float(mp_float_t val); mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); extern mp_float_t uint64_to_float(uint64_t ui64); +extern uint64_t float_to_uint64(float f); #endif mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); diff --git a/py/objarray.c b/py/objarray.c index e0b4cbd55f..9640f596a3 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -238,6 +238,26 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, return MP_OBJ_FROM_PTR(self); } + +#if MICROPY_CPYTHON_COMPAT +STATIC mp_obj_t memoryview_cast(const mp_obj_t self_in, const mp_obj_t typecode_in) { + mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); + const char *typecode = mp_obj_str_get_str(typecode_in); + size_t element_size = mp_binary_get_size('@', typecode[0], NULL); + size_t bytelen = self->len * mp_binary_get_size('@', self->typecode & ~MP_OBJ_ARRAY_TYPECODE_FLAG_RW, NULL); + if (bytelen % element_size != 0) { + mp_raise_TypeError(translate("memoryview: length is not a multiple of itemsize")); + } + mp_obj_array_t *result = MP_OBJ_TO_PTR(mp_obj_new_memoryview(*typecode, bytelen / element_size, self->items)); + + // test if the object can be written to + if (self->typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW) { + result->typecode |= MP_OBJ_ARRAY_TYPECODE_FLAG_RW; // indicate writable buffer + } + return MP_OBJ_FROM_PTR(result); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(memoryview_cast_obj, memoryview_cast); +#endif #endif STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) { @@ -691,6 +711,15 @@ const mp_obj_type_t mp_type_bytearray = { #endif #if MICROPY_PY_BUILTINS_MEMORYVIEW + +#if MICROPY_CPYTHON_COMPAT +STATIC const mp_rom_map_elem_t memoryview_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_cast), MP_ROM_PTR(&memoryview_cast_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(memoryview_locals_dict, memoryview_locals_dict_table); +#endif + const mp_obj_type_t mp_type_memoryview = { { &mp_type_type }, .name = MP_QSTR_memoryview, @@ -700,6 +729,9 @@ const mp_obj_type_t mp_type_memoryview = { .binary_op = array_binary_op, .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, +#if MICROPY_CPYTHON_COMPAT + .locals_dict = (mp_obj_dict_t*)&memoryview_locals_dict, +#endif }; #endif diff --git a/py/objfloat.c b/py/objfloat.c index 80f10e816e..329a8b90e0 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -340,6 +340,15 @@ mp_float_t uint64_to_float(uint64_t ui64) { return (mp_float_t) ((uint32_t) (ui64 >> 32) * 4294967296.0f + (uint32_t) (ui64 & 0xffffffff)); } +// Convert a uint64_t to a 32-bit float to a uint64_t without invoking extra math routines. +// which are large. +// Assume f >= 0. +uint64_t float_to_uint64(float f) { + // 4294967296 = 2^32 + const uint32_t upper_half = (uint32_t) (f / 4294967296.0f); + const uint32_t lower_half = (uint32_t) f; + return (((uint64_t) upper_half) << 32) + lower_half; +} #pragma GCC diagnostic pop #endif // MICROPY_PY_BUILTINS_FLOAT diff --git a/py/stream.c b/py/stream.c index ae702bb1b6..0813c1d7f2 100644 --- a/py/stream.c +++ b/py/stream.c @@ -99,14 +99,22 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) { STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte flags) { // What to do if sz < -1? Python docs don't specify this case. - // CPython does a readall, but here we silently let negatives through, - // and they will cause a MemoryError. + // CPython does a readall, let's do the same. mp_int_t sz; - if (n_args == 1 || args[1] == mp_const_none || ((sz = mp_obj_get_int(args[1])) == -1)) { - return stream_readall(args[0]); - } - const mp_stream_p_t *stream_p = mp_get_stream(args[0]); + if (stream_p->pyserial_read_compatibility) { + // Pyserial defaults to sz=1 if not specified. + if (n_args == 1) { + sz = 1; + } else { + // Pyserial treats negative size as 0. + sz = MAX(0, mp_obj_get_int(args[1])); + } + } else { + if (n_args == 1 || args[1] == mp_const_none || (sz = mp_obj_get_int(args[1])) <= -1) { + return stream_readall(args[0]); + } + } #if MICROPY_PY_BUILTINS_STR_UNICODE if (stream_p->is_text) { @@ -284,7 +292,7 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) { // https://docs.python.org/3/library/socket.html#socket.socket.recv_into mp_uint_t len = bufinfo.len; if (n_args > 2) { - if (mp_get_stream(args[0])->pyserial_compatibility) { + if (mp_get_stream(args[0])->pyserial_readinto_compatibility) { mp_raise_ValueError(translate("length argument not allowed for this type")); } len = mp_obj_get_int(args[2]); @@ -297,7 +305,10 @@ STATIC mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) { mp_uint_t out_sz = mp_stream_read_exactly(args[0], bufinfo.buf, len, &error); if (error != 0) { if (mp_is_nonblocking_error(error)) { - return mp_const_none; + // pyserial readinto never returns None, just 0. + return mp_get_stream(args[0])->pyserial_dont_return_none_compatibility + ? MP_OBJ_NEW_SMALL_INT(0) + : mp_const_none; } mp_raise_OSError(error); } else { @@ -323,7 +334,10 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) { // If we read nothing, return None, just like read(). // Otherwise, return data read so far. if (total_size == 0) { - return mp_const_none; + // pyserial read() never returns None, just b''. + return stream_p->pyserial_dont_return_none_compatibility + ? mp_const_empty_bytes + : mp_const_none; } break; } diff --git a/py/stream.h b/py/stream.h index be6b23d40d..c05dcfc501 100644 --- a/py/stream.h +++ b/py/stream.h @@ -72,7 +72,9 @@ typedef struct _mp_stream_p_t { mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode); mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode); mp_uint_t is_text : 1; // default is bytes, set this for text stream - bool pyserial_compatibility: 1; // adjust API to match pyserial more closely + bool pyserial_readinto_compatibility: 1; // Disallow size parameter in readinto() + bool pyserial_read_compatibility: 1; // Disallow omitting read(size) size parameter + bool pyserial_dont_return_none_compatibility: 1; // Don't return None for read() or readinto() } mp_stream_p_t; MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj); diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index 4d6c836c13..333b275ffb 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -231,8 +231,8 @@ STATIC const mp_stream_p_t characteristic_buffer_stream_p = { .write = bleio_characteristic_buffer_write, .ioctl = bleio_characteristic_buffer_ioctl, .is_text = false, - // Match PySerial when possible, such as disallowing optional length argument for .readinto() - .pyserial_compatibility = true, + // Disallow readinto() size parameter. + .pyserial_readinto_compatibility = true, }; diff --git a/shared-bindings/_pew/__init__.c b/shared-bindings/_pew/__init__.c index 498beaf1c9..912d267c4c 100644 --- a/shared-bindings/_pew/__init__.c +++ b/shared-bindings/_pew/__init__.c @@ -29,6 +29,7 @@ #include "PewPew.h" #include "common-hal/_pew/PewPew.h" + STATIC mp_obj_t get_pressed(void) { pew_obj_t *pew = MP_STATE_VM(pew_singleton); if (!pew) { @@ -41,12 +42,19 @@ STATIC mp_obj_t get_pressed(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_pressed_obj, get_pressed); +STATIC mp_obj_t get_ticks(void) { + return mp_obj_new_int(pew_get_ticks()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_ticks_obj, get_ticks); + + //| """LED matrix driver""" //| STATIC const mp_rom_map_elem_t pew_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pew) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PewPew), MP_ROM_PTR(&pewpew_type)}, { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&get_pressed_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_get_ticks), MP_ROM_PTR(&get_ticks_obj)}, }; STATIC MP_DEFINE_CONST_DICT(pew_module_globals, pew_module_globals_table); diff --git a/shared-bindings/adafruit_bus_device/SPIDevice.c b/shared-bindings/adafruit_bus_device/SPIDevice.c index e37f883682..74fa28e4d5 100644 --- a/shared-bindings/adafruit_bus_device/SPIDevice.c +++ b/shared-bindings/adafruit_bus_device/SPIDevice.c @@ -34,7 +34,6 @@ #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" #include "py/runtime.h" #include "supervisor/shared/translate.h" @@ -123,29 +122,9 @@ STATIC mp_obj_t adafruit_bus_device_spidevice_obj___exit__(size_t n_args, const } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_spidevice___exit___obj, 4, 4, adafruit_bus_device_spidevice_obj___exit__); -//| spi: busio.SPI -//| """The underlying SPI bus. Useful for weird uses like clocking an SD card without chip select. -//| -//| You shouldn't normally need this.""" -//| -STATIC mp_obj_t adafruit_bus_device_spidevice_obj_get_spi(mp_obj_t self_in) { - adafruit_bus_device_spidevice_obj_t *self = MP_OBJ_TO_PTR(self_in); - return common_hal_adafruit_bus_device_spidevice_get_spi(self); -} -MP_DEFINE_CONST_FUN_OBJ_1(adafruit_bus_device_spidevice_get_spi_obj, adafruit_bus_device_spidevice_obj_get_spi); - -const mp_obj_property_t adafruit_bus_device_spidevice_spi_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&adafruit_bus_device_spidevice_get_spi_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - STATIC const mp_rom_map_elem_t adafruit_bus_device_spidevice_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&adafruit_bus_device_spidevice___enter___obj) }, { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&adafruit_bus_device_spidevice___exit___obj) }, - - { MP_ROM_QSTR(MP_QSTR_spi), MP_ROM_PTR(&adafruit_bus_device_spidevice_spi_obj) }, }; STATIC MP_DEFINE_CONST_DICT(adafruit_bus_device_spidevice_locals_dict, adafruit_bus_device_spidevice_locals_dict_table); diff --git a/shared-bindings/adafruit_bus_device/SPIDevice.h b/shared-bindings/adafruit_bus_device/SPIDevice.h index baa9ec464a..997e22a6bd 100644 --- a/shared-bindings/adafruit_bus_device/SPIDevice.h +++ b/shared-bindings/adafruit_bus_device/SPIDevice.h @@ -46,6 +46,5 @@ extern void common_hal_adafruit_bus_device_spidevice_construct(adafruit_bus_devi uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t extra_clocks); extern mp_obj_t common_hal_adafruit_bus_device_spidevice_enter(adafruit_bus_device_spidevice_obj_t *self); extern void common_hal_adafruit_bus_device_spidevice_exit(adafruit_bus_device_spidevice_obj_t *self); -extern mp_obj_t common_hal_adafruit_bus_device_spidevice_get_spi(adafruit_bus_device_spidevice_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSDEVICE_SPIDEVICE_H diff --git a/shared-bindings/bitops/__init__.c b/shared-bindings/bitops/__init__.c new file mode 100644 index 0000000000..3c567b8ed9 --- /dev/null +++ b/shared-bindings/bitops/__init__.c @@ -0,0 +1,101 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/bitops/__init__.h" + +//| """Routines for low-level manipulation of binary data""" +//| +//| + +//| def bit_transpose(input: ReadableBuffer, output: WriteableBuffer, width:int = 8) -> WriteableBuffer: +//| """"Transpose" a buffer by assembling each output byte with bits taken from each of ``width`` different input bytes. +//| +//| This can be useful to convert a sequence of pixel values into a single +//| stream of bytes suitable for sending via a parallel conversion method. +//| +//| The number of bytes in the input buffer must be a multiple of the width, +//| and the width can be any value from 2 to 8. If the width is fewer than 8, +//| then the remaining (less significant) bits of the output are set to zero. +//| +//| Let ``stride = len(input)//width``. Then the first byte is made out of the +//| most significant bits of ``[input[0], input[stride], input[2*stride], ...]``. +//| The second byte is made out of the second bits, and so on until the 8th output +//| byte which is made of the first bits of ``input[1], input[1+stride, +//| input[2*stride], ...]``. +//| +//| The required output buffer size is ``len(input) * 8 // width``. +//| +//| Returns the output buffer.""" +//| ... + +STATIC mp_obj_t bit_transpose(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_input, ARG_output, ARG_width }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_input, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_output, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_width, MP_ARG_INT, { .u_int = 8 } }, + }; + 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); + + int width = args[ARG_width].u_int; + if (width < 2 || width > 8) { + mp_raise_ValueError_varg(translate("width must be from 2 to 8 (inclusive), not %d"), width); + } + + mp_buffer_info_t input_bufinfo; + mp_get_buffer_raise(args[ARG_input].u_obj, &input_bufinfo, MP_BUFFER_READ); + int inlen = input_bufinfo.len; + if (inlen % width != 0) { + mp_raise_ValueError_varg(translate("Input buffer length (%d) must be a multiple of the strand count (%d)"), inlen, width); + } + + mp_buffer_info_t output_bufinfo; + mp_get_buffer_raise(args[ARG_output].u_obj, &output_bufinfo, MP_BUFFER_WRITE); + int avail = output_bufinfo.len; + int outlen = 8 * (inlen / width); + if (avail < outlen) { + mp_raise_ValueError_varg(translate("Output buffer must be at least %d bytes"), outlen); + } + common_hal_bitops_bit_transpose(output_bufinfo.buf, input_bufinfo.buf, inlen, width); + return args[ARG_output].u_obj; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bitops_bit_transpose_obj, 1, bit_transpose); + +STATIC const mp_rom_map_elem_t bitops_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitops) }, + { MP_ROM_QSTR(MP_QSTR_bit_transpose), MP_ROM_PTR(&bitops_bit_transpose_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bitops_module_globals, bitops_module_globals_table); + +const mp_obj_module_t bitops_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&bitops_module_globals, +}; diff --git a/shared-bindings/bitops/__init__.h b/shared-bindings/bitops/__init__.h new file mode 100644 index 0000000000..6654cac5e9 --- /dev/null +++ b/shared-bindings/bitops/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include +#include + +void common_hal_bitops_bit_transpose(uint8_t *result, const uint8_t *src, size_t inlen, size_t num_strands); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index bf0b7e721d..f48109fdef 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -415,8 +415,8 @@ STATIC const mp_stream_p_t uart_stream_p = { .write = busio_uart_write, .ioctl = busio_uart_ioctl, .is_text = false, - // Match PySerial when possible, such as disallowing optional length argument for .readinto() - .pyserial_compatibility = true, + // Disallow optional length argument for .readinto() + .pyserial_readinto_compatibility = true, }; const mp_obj_type_t busio_uart_type = { diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index 975f8b0953..35d6c14973 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -55,6 +55,12 @@ //| Data transfers use the specified baurate (rounded down to one that is supported by //| the microcontroller) //| +//| .. important:: +//| If the same SPI bus is shared with other peripherals, it is important that +//| the SD card be initialized before accessing any other peripheral on the bus. +//| Failure to do so can prevent the SD card from being recognized until it is +//| powered off or re-inserted. +//| //| Example usage: //| //| .. code-block:: python diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 27440487a7..da827798c4 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -72,7 +72,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t ip[4]; - uint port; + uint32_t port; socketpool_socket_obj_t * sock = common_hal_socketpool_socket_accept(self, ip, &port); @@ -98,8 +98,11 @@ STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { size_t hostlen; const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); mp_int_t port = mp_obj_get_int(addr_items[1]); + if (port < 0) { + mp_raise_ValueError(translate("port must be >= 0")); + } - bool ok = common_hal_socketpool_socket_bind(self, host, hostlen, port); + bool ok = common_hal_socketpool_socket_bind(self, host, hostlen, (uint32_t)port); if (!ok) { mp_raise_ValueError(translate("Error: Failure to bind")); } @@ -133,8 +136,11 @@ STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { size_t hostlen; const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); mp_int_t port = mp_obj_get_int(addr_items[1]); + if (port < 0) { + mp_raise_ValueError(translate("port must be >= 0")); + } - bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, port); + bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, (uint32_t)port); if (!ok) { mp_raise_OSError(0); } @@ -278,8 +284,11 @@ STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_ size_t hostlen; const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); mp_int_t port = mp_obj_get_int(addr_items[1]); + if (port < 0) { + mp_raise_ValueError(translate("port must be >= 0")); + } - mp_int_t ret = common_hal_socketpool_socket_sendto(self, host, hostlen, port, bufinfo.buf, bufinfo.len); + mp_int_t ret = common_hal_socketpool_socket_sendto(self, host, hostlen, (uint32_t)port, bufinfo.buf, bufinfo.len); if (!ret) { mp_raise_OSError(0); } diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index 637a7a2146..27173c8b3f 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -31,20 +31,20 @@ extern const mp_obj_type_t socketpool_socket_type; -socketpool_socket_obj_t * common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self, uint8_t* ip, uint *port); -bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self, const char* host, size_t hostlen, uint8_t port); +socketpool_socket_obj_t * common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self, uint8_t* ip, uint32_t *port); +bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self, const char* host, size_t hostlen, uint32_t port); void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self); -bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, size_t hostlen, mp_int_t port); +bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, size_t hostlen, uint32_t port); bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self); bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self); mp_uint_t common_hal_socketpool_socket_get_timeout(socketpool_socket_obj_t* self); bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t* self, int backlog); mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* self, - uint8_t* buf, mp_uint_t len, uint8_t* ip, uint *port); -mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); -mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len); + uint8_t* buf, uint32_t len, uint8_t* ip, uint32_t *port); +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, uint32_t len); +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, uint32_t len); mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self, - const char* host, size_t hostlen, uint8_t port, const uint8_t* buf, mp_uint_t len); -void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms); + const char* host, size_t hostlen, uint32_t port, const uint8_t* buf, uint32_t len); +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, uint32_t timeout_ms); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index a937952a5d..0daa930ef7 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -71,7 +71,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket___exit___obj, 4, 4, ssl STATIC mp_obj_t ssl_sslsocket_accept(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); uint8_t ip[4]; - uint port; + uint32_t port; ssl_sslsocket_obj_t * sslsock = common_hal_ssl_sslsocket_accept(self, ip, &port); @@ -97,8 +97,11 @@ STATIC mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { size_t hostlen; const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); mp_int_t port = mp_obj_get_int(addr_items[1]); + if (port < 0) { + mp_raise_ValueError(translate("port must be >= 0")); + } - bool ok = common_hal_ssl_sslsocket_bind(self, host, hostlen, port); + bool ok = common_hal_ssl_sslsocket_bind(self, host, hostlen, (uint32_t)port); if (!ok) { mp_raise_ValueError(translate("Error: Failure to bind")); } @@ -132,8 +135,11 @@ STATIC mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) { size_t hostlen; const char* host = mp_obj_str_get_data(addr_items[0], &hostlen); mp_int_t port = mp_obj_get_int(addr_items[1]); + if (port < 0) { + mp_raise_ValueError(translate("port must be >= 0")); + } - bool ok = common_hal_ssl_sslsocket_connect(self, host, hostlen, port); + bool ok = common_hal_ssl_sslsocket_connect(self, host, hostlen, (uint32_t)port); if (!ok) { mp_raise_OSError(0); } diff --git a/shared-bindings/ssl/SSLSocket.h b/shared-bindings/ssl/SSLSocket.h index b1f2c513d7..d117e5dca2 100644 --- a/shared-bindings/ssl/SSLSocket.h +++ b/shared-bindings/ssl/SSLSocket.h @@ -31,15 +31,15 @@ extern const mp_obj_type_t ssl_sslsocket_type; -ssl_sslsocket_obj_t * common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t* self, uint8_t* ip, uint *port); -bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t* self, const char* host, size_t hostlen, uint8_t port); +ssl_sslsocket_obj_t * common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t* self, uint8_t* ip, uint32_t *port); +bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t* self, const char* host, size_t hostlen, uint32_t port); void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t* self); -bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t* self, const char* host, size_t hostlen, mp_int_t port); +bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t* self, const char* host, size_t hostlen, uint32_t port); bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t* self); bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t* self); bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t* self, int backlog); -mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len); -mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t* buf, mp_uint_t len); -void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t* self, mp_uint_t timeout_ms); +mp_uint_t common_hal_ssl_sslsocket_recv_into(ssl_sslsocket_obj_t* self, const uint8_t* buf, uint32_t len); +mp_uint_t common_hal_ssl_sslsocket_send(ssl_sslsocket_obj_t* self, const uint8_t* buf, uint32_t len); +void common_hal_ssl_sslsocket_settimeout(ssl_sslsocket_obj_t* self, uint32_t timeout_ms); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SSL_SSLSOCKET_H diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 8e0259a3b3..283c8a1d6c 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -55,59 +55,46 @@ STATIC supervisor_run_reason_t _run_reason; //| serial_connected: bool //| """Returns the USB serial communication status (read-only).""" //| - -STATIC mp_obj_t supervisor_get_serial_connected(mp_obj_t self){ - if (!common_hal_get_serial_connected()) { - return mp_const_false; - } - else { - return mp_const_true; - } +STATIC mp_obj_t supervisor_runtime_get_serial_connected(mp_obj_t self){ + return mp_obj_new_bool(common_hal_supervisor_runtime_get_serial_connected()); } -MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_connected_obj, supervisor_get_serial_connected); +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_serial_connected_obj, supervisor_runtime_get_serial_connected); -const mp_obj_property_t supervisor_serial_connected_obj = { +const mp_obj_property_t supervisor_runtime_serial_connected_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&supervisor_get_serial_connected_obj, + .proxy = {(mp_obj_t)&supervisor_runtime_get_serial_connected_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; - //| serial_bytes_available: int //| """Returns the whether any bytes are available to read //| on the USB serial input. Allows for polling to see whether //| to call the built-in input() or wait. (read-only)""" //| -STATIC mp_obj_t supervisor_get_serial_bytes_available(mp_obj_t self){ - if (!common_hal_get_serial_bytes_available()) { - return mp_const_false; - } - else { - return mp_const_true; - } +STATIC mp_obj_t supervisor_runtime_get_serial_bytes_available(mp_obj_t self){ + return mp_obj_new_bool(common_hal_supervisor_runtime_get_serial_bytes_available()); } -MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_serial_bytes_available_obj, supervisor_get_serial_bytes_available); +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_serial_bytes_available_obj, supervisor_runtime_get_serial_bytes_available); -const mp_obj_property_t supervisor_serial_bytes_available_obj = { +const mp_obj_property_t supervisor_runtime_serial_bytes_available_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&supervisor_get_serial_bytes_available_obj, + .proxy = {(mp_obj_t)&supervisor_runtime_get_serial_bytes_available_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; - //| run_reason: RunReason //| """Returns why CircuitPython started running this particular time.""" //| -STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { +STATIC mp_obj_t supervisor_runtime_get_run_reason(mp_obj_t self) { return cp_enum_find(&supervisor_run_reason_type, _run_reason); } -MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_run_reason_obj, supervisor_get_run_reason); +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_run_reason_obj, supervisor_runtime_get_run_reason); -const mp_obj_property_t supervisor_run_reason_obj = { +const mp_obj_property_t supervisor_runtime_run_reason_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&supervisor_get_run_reason_obj, + .proxy = {(mp_obj_t)&supervisor_runtime_get_run_reason_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -117,9 +104,9 @@ void supervisor_set_run_reason(supervisor_run_reason_t run_reason) { } STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_serial_bytes_available_obj) }, - { MP_ROM_QSTR(MP_QSTR_run_reason), MP_ROM_PTR(&supervisor_run_reason_obj) }, + { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_runtime_serial_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_runtime_serial_bytes_available_obj) }, + { MP_ROM_QSTR(MP_QSTR_run_reason), MP_ROM_PTR(&supervisor_runtime_run_reason_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index 51ed7604df..6874ac744a 100755 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -36,12 +36,12 @@ extern const mp_obj_type_t supervisor_runtime_type; void supervisor_set_run_reason(supervisor_run_reason_t run_reason); -bool common_hal_get_serial_connected(void); +bool common_hal_supervisor_runtime_get_serial_connected(void); -bool common_hal_get_serial_bytes_available(void); +bool common_hal_supervisor_runtime_get_serial_bytes_available(void); //TODO: placeholders for future functions -//bool common_hal_get_repl_active(void); -//bool common_hal_get_usb_enumerated(void); +//bool common_hal_get_supervisor_runtime_repl_active(void); +//bool common_hal_get_supervisor_runtime_usb_enumerated(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR_RUNTIME_H diff --git a/shared-bindings/usb_cdc/Serial.c b/shared-bindings/usb_cdc/Serial.c new file mode 100644 index 0000000000..c813dce5b3 --- /dev/null +++ b/shared-bindings/usb_cdc/Serial.c @@ -0,0 +1,293 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "shared-bindings/usb_cdc/Serial.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + +//| class Serial: +//| """Receives cdc commands over USB""" +//| +//| def __init__(self) -> None: +//| """You cannot create an instance of `usb_cdc.Serial`. +//| +//| Serial objects are pre-constructed for each CDC device in the USB +//| descriptor and added to the ``usb_cdc.ports`` tuple.""" +//| ... +//| + +//| def read(self, size: int = 1) -> bytes: +//| """Read at most ``size`` bytes. If ``size`` exceeds the internal buffer size +//| only the bytes in the buffer will be read. If `timeout` is > 0 or ``None``, +//| and fewer than ``size`` bytes are available, keep waiting until the timeout +//| expires or ``size`` bytes are available. +//| +//| :return: Data read +//| :rtype: bytes""" +//| ... +//| +//| def readinto(self, buf: WriteableBuffer) -> int: +//| """Read bytes into the ``buf``. If ``nbytes`` is specified then read at most +//| that many bytes, subject to `timeout`. Otherwise, read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: bytes""" +//| ... +//| +//| def write(self, buf: ReadableBuffer) -> int: +//| """Write as many bytes as possible from the buffer of bytes. +//| +//| :return: the number of bytes written +//| :rtype: int""" +//| ... +//| +//| def flush(self) -> None: +//| """Force out any unwritten bytes, waiting until they are written.""" +//| ... +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t usb_cdc_serial_read_stream(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_usb_cdc_serial_read(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_cdc_serial_write_stream(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_usb_cdc_serial_write(self, buf, size, errcode); +} + +STATIC mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret = 0; + switch (request) { + case MP_IOCTL_POLL: { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) { + ret |= MP_IOCTL_POLL_WR; + } + break; + } + + case MP_STREAM_FLUSH: + common_hal_usb_cdc_serial_flush(self); + break; + + default: + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +//| connected: bool +//| """True if this Serial is connected to a host. (read-only)""" +//| +STATIC mp_obj_t usb_cdc_serial_get_connected(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_usb_cdc_serial_get_connected(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_connected_obj, usb_cdc_serial_get_connected); + +const mp_obj_property_t usb_cdc_serial_connected_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_cdc_serial_get_connected_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| in_waiting: int +//| """Returns the number of bytes waiting to be read on the USB serial input. (read-only)""" +//| +STATIC mp_obj_t usb_cdc_serial_get_in_waiting(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(common_hal_usb_cdc_serial_get_in_waiting(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_in_waiting_obj, usb_cdc_serial_get_in_waiting); + +const mp_obj_property_t usb_cdc_serial_in_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_cdc_serial_get_in_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| out_waiting: int +//| """Returns the number of bytes waiting to be written on the USB serial output. (read-only)""" +//| +STATIC mp_obj_t usb_cdc_serial_get_out_waiting(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(common_hal_usb_cdc_serial_get_out_waiting(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_out_waiting_obj, usb_cdc_serial_get_out_waiting); + +const mp_obj_property_t usb_cdc_serial_out_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_cdc_serial_get_out_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| def reset_input_buffer(self) -> None: +//| """Clears any unread bytes.""" +//| ... +//| +STATIC mp_obj_t usb_cdc_serial_reset_input_buffer(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_cdc_serial_reset_input_buffer(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_input_buffer_obj, usb_cdc_serial_reset_input_buffer); + +//| def reset_output_buffer(self) -> None: +//| """Clears any unwritten bytes.""" +//| ... +//| +STATIC mp_obj_t usb_cdc_serial_reset_output_buffer(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_cdc_serial_reset_output_buffer(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_output_buffer_obj, usb_cdc_serial_reset_output_buffer); + +//| timeout: Optional[float] +//| """The initial value of `timeout` is ``None``. If ``None``, wait indefinitely to satisfy +//| the conditions of a read operation. If 0, do not wait. If > 0, wait only ``timeout`` seconds.""" +//| +STATIC mp_obj_t usb_cdc_serial_get_timeout(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_float_t timeout = common_hal_usb_cdc_serial_get_timeout(self); + return (timeout < 0.0f) ? mp_const_none : mp_obj_new_float(self->timeout); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_timeout_obj, usb_cdc_serial_get_timeout); + +STATIC mp_obj_t usb_cdc_serial_set_timeout(mp_obj_t self_in, mp_obj_t timeout_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_cdc_serial_set_timeout(self, + timeout_in == mp_const_none ? -1.0f : mp_obj_get_float(timeout_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(usb_cdc_serial_set_timeout_obj, usb_cdc_serial_set_timeout); + +const mp_obj_property_t usb_cdc_serial_timeout_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_cdc_serial_get_timeout_obj, + (mp_obj_t)&usb_cdc_serial_set_timeout_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| write_timeout: Optional[float] +//| """The initial value of `write_timeout` is ``None``. If ``None``, wait indefinitely to finish +//| writing all the bytes passed to ``write()``.If 0, do not wait. +//| If > 0, wait only ``write_timeout`` seconds.""" +//| +STATIC mp_obj_t usb_cdc_serial_get_write_timeout(mp_obj_t self_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_float_t write_timeout = common_hal_usb_cdc_serial_get_write_timeout(self); + return (write_timeout < 0.0f) ? mp_const_none : mp_obj_new_float(self->write_timeout); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_write_timeout_obj, usb_cdc_serial_get_write_timeout); + +STATIC mp_obj_t usb_cdc_serial_set_write_timeout(mp_obj_t self_in, mp_obj_t write_timeout_in) { + usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_cdc_serial_set_write_timeout(self, + write_timeout_in == mp_const_none ? -1.0f : mp_obj_get_float(write_timeout_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(usb_cdc_serial_set_write_timeout_obj, usb_cdc_serial_set_write_timeout); + +const mp_obj_property_t usb_cdc_serial_write_timeout_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_cdc_serial_get_write_timeout_obj, + (mp_obj_t)&usb_cdc_serial_set_write_timeout_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +STATIC const mp_rom_map_elem_t usb_cdc_serial_locals_dict_table[] = { + // Standard stream methods. + { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + + // Other pyserial-inspired attributes. + { MP_OBJ_NEW_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&usb_cdc_serial_in_waiting_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_out_waiting), MP_ROM_PTR(&usb_cdc_serial_out_waiting_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_input_buffer_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_reset_output_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_output_buffer_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&usb_cdc_serial_timeout_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write_timeout), MP_ROM_PTR(&usb_cdc_serial_write_timeout_obj) }, + + // Not in pyserial protocol. + { MP_OBJ_NEW_QSTR(MP_QSTR_connected), MP_ROM_PTR(&usb_cdc_serial_connected_obj) }, + + + +}; +STATIC MP_DEFINE_CONST_DICT(usb_cdc_serial_locals_dict, usb_cdc_serial_locals_dict_table); + +STATIC const mp_stream_p_t usb_cdc_serial_stream_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) + .read = usb_cdc_serial_read_stream, + .write = usb_cdc_serial_write_stream, + .ioctl = usb_cdc_serial_ioctl_stream, + .is_text = false, + .pyserial_read_compatibility = true, + .pyserial_readinto_compatibility = true, + .pyserial_dont_return_none_compatibility = true, +}; + +const mp_obj_type_t usb_cdc_serial_type = { + { &mp_type_type }, + .name = MP_QSTR_Serial, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &usb_cdc_serial_stream_p, + .locals_dict = (mp_obj_dict_t*)&usb_cdc_serial_locals_dict, +}; diff --git a/shared-bindings/usb_cdc/Serial.h b/shared-bindings/usb_cdc/Serial.h new file mode 100644 index 0000000000..cdf5c3a914 --- /dev/null +++ b/shared-bindings/usb_cdc/Serial.h @@ -0,0 +1,53 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H + +#include "shared-module/usb_cdc/Serial.h" + +extern const mp_obj_type_t usb_cdc_serial_type; + +extern size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, size_t len, int *errcode); +extern size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_usb_cdc_serial_get_in_waiting(usb_cdc_serial_obj_t *self); +extern uint32_t common_hal_usb_cdc_serial_get_out_waiting(usb_cdc_serial_obj_t *self); + +extern void common_hal_usb_cdc_serial_reset_input_buffer(usb_cdc_serial_obj_t *self); +extern uint32_t common_hal_usb_cdc_serial_reset_output_buffer(usb_cdc_serial_obj_t *self); + +extern uint32_t common_hal_usb_cdc_serial_flush(usb_cdc_serial_obj_t *self); + +extern bool common_hal_usb_cdc_serial_get_connected(usb_cdc_serial_obj_t *self); + +extern mp_float_t common_hal_usb_cdc_serial_get_timeout(usb_cdc_serial_obj_t *self); +extern void common_hal_usb_cdc_serial_set_timeout(usb_cdc_serial_obj_t *self, mp_float_t timeout); + +extern mp_float_t common_hal_usb_cdc_serial_get_write_timeout(usb_cdc_serial_obj_t *self); +extern void common_hal_usb_cdc_serial_set_write_timeout(usb_cdc_serial_obj_t *self, mp_float_t write_timeout); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC_SERIAL_H diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c new file mode 100644 index 0000000000..eb9c25e001 --- /dev/null +++ b/shared-bindings/usb_cdc/__init__.c @@ -0,0 +1,59 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbertfor Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_cdc/__init__.h" +#include "shared-bindings/usb_cdc/Serial.h" + +#include "py/runtime.h" + +//| """USB CDC Serial streams +//| +//| The `usb_cdc` module allows access to USB CDC (serial) communications.""" +//| +//| serials: Tuple[Serial, ...] +//| """Tuple of all CDC streams. Each item is a `Serial`. +//| ``serials[0]`` is the USB REPL connection. +//| ``serials[1]`` is a second USB serial connection, unconnected to the REPL. +//| """ +//| + +static const mp_map_elem_t usb_cdc_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_cdc) }, + { MP_ROM_QSTR(MP_QSTR_Serial), MP_OBJ_FROM_PTR(&usb_cdc_serial_type) }, + { MP_ROM_QSTR(MP_QSTR_serials), MP_OBJ_FROM_PTR(&usb_cdc_serials_tuple) }, +}; + +static MP_DEFINE_CONST_DICT(usb_cdc_module_globals, usb_cdc_module_globals_table); + +const mp_obj_module_t usb_cdc_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&usb_cdc_module_globals, +}; diff --git a/shared-bindings/usb_cdc/__init__.h b/shared-bindings/usb_cdc/__init__.h new file mode 100644 index 0000000000..e81d243e6c --- /dev/null +++ b/shared-bindings/usb_cdc/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H + +#include "shared-module/usb_cdc/__init__.h" + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_CDC___INIT___H diff --git a/shared-module/adafruit_bus_device/SPIDevice.c b/shared-module/adafruit_bus_device/SPIDevice.c index 5c1a69b128..65649026a6 100644 --- a/shared-module/adafruit_bus_device/SPIDevice.c +++ b/shared-module/adafruit_bus_device/SPIDevice.c @@ -84,7 +84,3 @@ void common_hal_adafruit_bus_device_spidevice_exit(adafruit_bus_device_spidevice common_hal_busio_spi_unlock(self->spi); } - -mp_obj_t common_hal_adafruit_bus_device_spidevice_get_spi(adafruit_bus_device_spidevice_obj_t *self) { - return self->spi; -} diff --git a/shared-module/bitops/__init__.c b/shared-module/bitops/__init__.c new file mode 100644 index 0000000000..cf0ac7bd1f --- /dev/null +++ b/shared-module/bitops/__init__.c @@ -0,0 +1,151 @@ +/* + * This file is part of the Circuit Python project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/bitops/__init__.h" + +#include +#include +#include + +#ifdef __GNUC__ +#define FALLTHROUGH __attribute__((fallthrough)) +#else +#define FALLTHROUGH ((void)0) /* FALLTHROUGH */ +#endif + +// adapted from "Hacker's Delight" - Figure 7-2 Transposing an 8x8-bit matrix +// basic idea is: +// > First, treat the 8x8-bit matrix as 16 2x2-bit matrices, and transpose each +// > of the 16 2x2-bit matrices. Second, treat the matrix as four 2x2 submatrices +// > whose elements are 2x2-bit matrices and transpose each of the four 2x2 +// > submatrices. Finally, treat the matrix as a 2x2 matrix whose elements are +// > 4x4-bit matrices, and transpose the 2x2 matrix. These transformations are +// > illustrated below. +// We want a different definition of bit/byte order, deal with strides differently, etc. +// so the code is heavily re-worked compared to the original. +static void transpose_var(uint32_t *result, const uint8_t *src, int src_stride, int num_strands) { + uint32_t x = 0, y = 0, t; + + src += (num_strands-1) * src_stride; + + switch(num_strands) { + case 7: + x |= *src << 16; + src -= src_stride; + FALLTHROUGH; + case 6: + x |= *src << 8; + src -= src_stride; + FALLTHROUGH; + case 5: + x |= *src; + src -= src_stride; + FALLTHROUGH; + case 4: + y |= *src << 24; + src -= src_stride; + FALLTHROUGH; + case 3: + y |= *src << 16; + src -= src_stride; + FALLTHROUGH; + case 2: + y |= *src << 8; + src -= src_stride; + y |= *src; + } + + t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); + t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); + + t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); + t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); + + t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); + y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); + x = t; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + x = __builtin_bswap32(x); + y = __builtin_bswap32(y); +#endif + result[0] = x; + result[1] = y; +} + +static void transpose_8(uint32_t *result, const uint8_t *src, int src_stride) { + uint32_t x, y, t; + + y = *src; src += src_stride; + y |= (*src << 8); src += src_stride; + y |= (*src << 16); src += src_stride; + y |= (*src << 24); src += src_stride; + x = *src; src += src_stride; + x |= (*src << 8); src += src_stride; + x |= (*src << 16); src += src_stride; + x |= (*src << 24); src += src_stride; + + t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7); + t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7); + + t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14); + t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14); + + t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F); + y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F); + x = t; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + x = __builtin_bswap32(x); + y = __builtin_bswap32(y); +#endif + result[0] = x; + result[1] = y; +} + +static void bit_transpose_8(uint32_t *result, const uint8_t *src, size_t src_stride, size_t n) { + for(size_t i=0; itimeout < 0.0f; + const bool wait_for_timeout = self->timeout > 0.0f; + + // Read up to len bytes immediately. + // The number of bytes read will not be larger than what is already in the TinyUSB FIFO. + uint32_t total_num_read = tud_cdc_n_read(self->idx, data, len); + + if (wait_forever || wait_for_timeout) { + // Read more if we have time. + // Use special routine to avoid pulling in uint64-float-compatible math routines. + uint64_t timeout_ms = float_to_uint64(self->timeout * 1000); // Junk value if timeout < 0. + uint64_t start_ticks = supervisor_ticks_ms64(); + + uint32_t num_read = 0; + while (total_num_read < len && + (wait_forever || supervisor_ticks_ms64() - start_ticks <= timeout_ms)) { + + // Wait for a bit, and check for ctrl-C. + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return 0; + } + + // Advance buffer pointer and reduce number of bytes that need to be read. + len -= num_read; + data += num_read; + + // Try to read another batch of bytes. + num_read = tud_cdc_n_read(self->idx, data, len); + total_num_read += num_read; + } + } + + return total_num_read; +} + +size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + const bool wait_forever = self->write_timeout < 0.0f; + const bool wait_for_timeout = self->write_timeout > 0.0f; + + // Write as many bytes as possible immediately. + // The number of bytes written at once will not be larger than what can fit in the TinyUSB FIFO. + uint32_t total_num_written = tud_cdc_n_write(self->idx, data, len); + tud_cdc_n_write_flush(self->idx); + + if (wait_forever || wait_for_timeout) { + // Write more if we have time. + // Use special routine to avoid pulling in uint64-float-compatible math routines. + uint64_t timeout_ms = float_to_uint64(self->write_timeout * 1000); // Junk value if write_timeout < 0. + uint64_t start_ticks = supervisor_ticks_ms64(); + + uint32_t num_written = 0; + while (total_num_written < len && + (wait_forever || supervisor_ticks_ms64() - start_ticks <= timeout_ms)) { + + // Wait for a bit, and check for ctrl-C. + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return 0; + } + + // Advance buffer pointer and reduce number of bytes that need to be written. + len -= num_written; + data += num_written; + + // Try to write another batch of bytes. + num_written = tud_cdc_n_write(self->idx, data, len); + tud_cdc_n_write_flush(self->idx); + total_num_written += num_written; + } + } + + return total_num_written; +} + +uint32_t common_hal_usb_cdc_serial_get_in_waiting(usb_cdc_serial_obj_t *self) { + return tud_cdc_n_available(self->idx); +} + +uint32_t common_hal_usb_cdc_serial_get_out_waiting(usb_cdc_serial_obj_t *self) { + // Return number of FIFO bytes currently occupied. + return CFG_TUD_CDC_TX_BUFSIZE - tud_cdc_n_write_available(self->idx); +} + +void common_hal_usb_cdc_serial_reset_input_buffer(usb_cdc_serial_obj_t *self) { + tud_cdc_n_read_flush(self->idx); +} + +uint32_t common_hal_usb_cdc_serial_reset_output_buffer(usb_cdc_serial_obj_t *self) { + return tud_cdc_n_write_clear(self->idx); +} + +uint32_t common_hal_usb_cdc_serial_flush(usb_cdc_serial_obj_t *self) { + return tud_cdc_n_write_flush(self->idx); +} + +bool common_hal_usb_cdc_serial_get_connected(usb_cdc_serial_obj_t *self) { + return tud_cdc_n_connected(self->idx); +} + +mp_float_t common_hal_usb_cdc_serial_get_timeout(usb_cdc_serial_obj_t *self) { + return self->timeout; +} + +void common_hal_usb_cdc_serial_set_timeout(usb_cdc_serial_obj_t *self, mp_float_t timeout) { + self->timeout = timeout; +} + +mp_float_t common_hal_usb_cdc_serial_get_write_timeout(usb_cdc_serial_obj_t *self) { + return self->write_timeout; +} + +void common_hal_usb_cdc_serial_set_write_timeout(usb_cdc_serial_obj_t *self, mp_float_t write_timeout) { + self->write_timeout = write_timeout; +} diff --git a/shared-module/usb_cdc/Serial.h b/shared-module/usb_cdc/Serial.h new file mode 100644 index 0000000000..ddf78eefa6 --- /dev/null +++ b/shared-module/usb_cdc/Serial.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert 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 SHARED_MODULE_USB_CDC_SERIAL_H +#define SHARED_MODULE_USB_CDC_SERIAL_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_float_t timeout; // if negative, wait forever. + mp_float_t write_timeout; // if negative, wait forever. + uint8_t idx; // which CDC device? +} usb_cdc_serial_obj_t; + +#endif // SHARED_MODULE_USB_CDC_SERIAL_H diff --git a/shared-module/usb_cdc/__init__.c b/shared-module/usb_cdc/__init__.c new file mode 100644 index 0000000000..fe05cb1075 --- /dev/null +++ b/shared-module/usb_cdc/__init__.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert 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 "genhdr/autogen_usb_descriptor.h" +#include "py/gc.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objtuple.h" +#include "shared-bindings/usb_cdc/__init__.h" +#include "shared-bindings/usb_cdc/Serial.h" +#include "tusb.h" + +#if CFG_TUD_CDC != 2 +#error CFG_TUD_CDC must be exactly 2 +#endif + +static usb_cdc_serial_obj_t serial_objs[CFG_TUD_CDC] = { + { .base.type = &usb_cdc_serial_type, + .timeout = -1.0f, + .write_timeout = -1.0f, + .idx = 0, + }, { + .base.type = &usb_cdc_serial_type, + .timeout = -1.0f, + .write_timeout = -1.0f, + .idx = 1, + } +}; + +const mp_rom_obj_tuple_t usb_cdc_serials_tuple = { + .base.type = &mp_type_tuple, + .len = CFG_TUD_CDC, + .items = { + &serial_objs[0], + &serial_objs[1], + }, +}; diff --git a/shared-module/usb_cdc/__init__.h b/shared-module/usb_cdc/__init__.h new file mode 100644 index 0000000000..9de3eb2faa --- /dev/null +++ b/shared-module/usb_cdc/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Dan Halbert 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 SHARED_MODULE_USB_CDC___INIT___H +#define SHARED_MODULE_USB_CDC___INIT___H + +#include "py/objtuple.h" + +extern const mp_rom_obj_tuple_t usb_cdc_serials_tuple; + +#endif /* SHARED_MODULE_USB_CDC___INIT___H */ diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index b9feb04f25..9cc12de512 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -118,7 +118,6 @@ bool serial_bytes_available(void) { return tud_cdc_available() > 0; #endif } - void serial_write_substring(const char* text, uint32_t length) { if (length == 0) { return; diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index d3a35f5374..bff7bd6b55 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -61,10 +61,15 @@ // DEVICE CONFIGURATION //--------------------------------------------------------------------+ -#define CFG_TUD_ENDOINT0_SIZE 64 +#define CFG_TUD_ENDPOINT0_SIZE 64 //------------- CLASS -------------// + +// Could be 2 if secondary CDC channel requested. +#ifndef CFG_TUD_CDC #define CFG_TUD_CDC 1 +#endif + #define CFG_TUD_MSC 1 #define CFG_TUD_HID CIRCUITPY_USB_HID #define CFG_TUD_MIDI CIRCUITPY_USB_MIDI diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 43564d5d5c..aa35b95e60 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -26,7 +26,6 @@ #include "py/objstr.h" #include "shared-bindings/microcontroller/Processor.h" -#include "shared-module/usb_midi/__init__.h" #include "supervisor/background_callback.h" #include "supervisor/port.h" #include "supervisor/serial.h" @@ -35,6 +34,10 @@ #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" +#if CIRCUITPY_USB_MIDI +#include "shared-module/usb_midi/__init__.h" +#endif + #include "tusb.h" #if CIRCUITPY_USB_VENDOR @@ -59,6 +62,7 @@ void load_serial_number(void) { uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH]; common_hal_mcu_processor_get_uid(raw_id); + usb_serial_number[0] = 0x300 | sizeof(usb_serial_number); for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) { for (int j = 0; j < 2; j++) { uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf; @@ -216,7 +220,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ return true; } -#endif CIRCUITPY_USB_VENDOR +#endif // CIRCUITPY_USB_VENDOR #if MICROPY_KBD_EXCEPTION diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index 080187ebc5..419a70ab30 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -43,12 +43,14 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { return usb_desc_cfg; } +#if CIRCUITPY_USB_HID // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(void) { return hid_report_descriptor; } +#endif // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index f559e004ef..374b7a72bd 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -14,23 +14,15 @@ SRC_SUPERVISOR = \ supervisor/shared/tick.c \ supervisor/shared/translate.c -ifndef $(NO_USB) - NO_USB = $(wildcard supervisor/usb.c) -endif +NO_USB ?= $(wildcard supervisor/usb.c) -ifndef INTERNAL_FLASH_FILESYSTEM -INTERNAL_FLASH_FILESYSTEM = 0 -endif +INTERNAL_FLASH_FILESYSTEM ?= 0 CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM) -ifndef QSPI_FLASH_FILESYSTEM -QSPI_FLASH_FILESYSTEM = 0 -endif +QSPI_FLASH_FILESYSTEM ?= 0 CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -ifndef SPI_FLASH_FILESYSTEM -SPI_FLASH_FILESYSTEM = 0 -endif +SPI_FLASH_FILESYSTEM ?= 0 CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) ifeq ($(CIRCUITPY_BLEIO),1) @@ -41,154 +33,180 @@ endif # (Right now INTERNAL_FLASH_FILESYSTEM and (Q)SPI_FLASH_FILESYSTEM are mutually exclusive. # But that might not be true in the future.) ifdef EXTERNAL_FLASH_DEVICES - CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \ - -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT) + CFLAGS += -DEXTERNAL_FLASH_DEVICES=$(EXTERNAL_FLASH_DEVICES) \ + -DEXTERNAL_FLASH_DEVICE_COUNT=$(EXTERNAL_FLASH_DEVICE_COUNT) - SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c - ifeq ($(SPI_FLASH_FILESYSTEM),1) - SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c - else - endif - ifeq ($(QSPI_FLASH_FILESYSTEM),1) - SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c - endif + SRC_SUPERVISOR += supervisor/shared/external_flash/external_flash.c + ifeq ($(SPI_FLASH_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/shared/external_flash/spi_flash.c + endif + ifeq ($(QSPI_FLASH_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c + endif else - ifeq ($(DISABLE_FILESYSTEM),1) - SRC_SUPERVISOR += supervisor/stub/internal_flash.c - else - SRC_SUPERVISOR += supervisor/internal_flash.c - endif + ifeq ($(DISABLE_FILESYSTEM),1) + SRC_SUPERVISOR += supervisor/stub/internal_flash.c + else + SRC_SUPERVISOR += supervisor/internal_flash.c + endif endif ifeq ($(USB),FALSE) - ifeq ($(wildcard supervisor/serial.c),) - SRC_SUPERVISOR += supervisor/stub/serial.c - else - SRC_SUPERVISOR += supervisor/serial.c - endif + ifeq ($(wildcard supervisor/serial.c),) + SRC_SUPERVISOR += supervisor/stub/serial.c + else + SRC_SUPERVISOR += supervisor/serial.c + endif else - SRC_SUPERVISOR += \ - lib/tinyusb/src/common/tusb_fifo.c \ - lib/tinyusb/src/device/usbd.c \ - lib/tinyusb/src/device/usbd_control.c \ - lib/tinyusb/src/class/msc/msc_device.c \ - lib/tinyusb/src/class/cdc/cdc_device.c \ - lib/tinyusb/src/tusb.c \ - supervisor/shared/serial.c \ - supervisor/shared/workflow.c \ - supervisor/usb.c \ - supervisor/shared/usb/usb_desc.c \ - supervisor/shared/usb/usb.c \ - supervisor/shared/usb/usb_msc_flash.c \ - $(BUILD)/autogen_usb_descriptor.c + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/cdc/cdc_device.c \ + lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/device/usbd_control.c \ + lib/tinyusb/src/tusb.c \ + supervisor/shared/serial.c \ + supervisor/shared/workflow.c \ + supervisor/usb.c \ + supervisor/shared/usb/usb_desc.c \ + supervisor/shared/usb/usb.c \ + $(BUILD)/autogen_usb_descriptor.c \ - ifeq ($(CIRCUITPY_USB_HID), 1) - SRC_SUPERVISOR += \ - lib/tinyusb/src/class/hid/hid_device.c \ - shared-bindings/usb_hid/__init__.c \ - shared-bindings/usb_hid/Device.c \ - shared-module/usb_hid/__init__.c \ - shared-module/usb_hid/Device.c - endif + ifeq ($(CIRCUITPY_USB_CDC), 1) + SRC_SUPERVISOR += \ + shared-bindings/usb_cdc/__init__.c \ + shared-bindings/usb_cdc/Serial.c \ + shared-module/usb_cdc/__init__.c \ + shared-module/usb_cdc/Serial.c \ - ifeq ($(CIRCUITPY_USB_MIDI), 1) - SRC_SUPERVISOR += \ - lib/tinyusb/src/class/midi/midi_device.c \ - shared-bindings/usb_midi/__init__.c \ - shared-bindings/usb_midi/PortIn.c \ - shared-bindings/usb_midi/PortOut.c \ - shared-module/usb_midi/__init__.c \ - shared-module/usb_midi/PortIn.c \ - shared-module/usb_midi/PortOut.c - endif + endif - ifeq ($(CIRCUITPY_USB_VENDOR), 1) - SRC_SUPERVISOR += \ - lib/tinyusb/src/class/vendor/vendor_device.c - endif + ifeq ($(CIRCUITPY_USB_HID), 1) + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/hid/hid_device.c \ + shared-bindings/usb_hid/__init__.c \ + shared-bindings/usb_hid/Device.c \ + shared-module/usb_hid/__init__.c \ + shared-module/usb_hid/Device.c \ - CFLAGS += -DUSB_AVAILABLE + endif + + ifeq ($(CIRCUITPY_USB_MIDI), 1) + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/midi/midi_device.c \ + shared-bindings/usb_midi/__init__.c \ + shared-bindings/usb_midi/PortIn.c \ + shared-bindings/usb_midi/PortOut.c \ + shared-module/usb_midi/__init__.c \ + shared-module/usb_midi/PortIn.c \ + shared-module/usb_midi/PortOut.c \ + + endif + + ifeq ($(CIRCUITPY_USB_MSC), 1) + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/msc/msc_device.c \ + supervisor/shared/usb/usb_msc_flash.c \ + + endif + + ifeq ($(CIRCUITPY_USB_VENDOR), 1) + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/vendor/vendor_device.c \ + + endif + + CFLAGS += -DUSB_AVAILABLE endif SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) ifeq ($(CIRCUITPY_DISPLAYIO), 1) - SRC_SUPERVISOR += \ - supervisor/shared/display.c + SRC_SUPERVISOR += \ + supervisor/shared/display.c - ifeq ($(CIRCUITPY_TERMINALIO), 1) - SUPERVISOR_O += $(BUILD)/autogen_display_resources.o - endif + ifeq ($(CIRCUITPY_TERMINALIO), 1) + SUPERVISOR_O += $(BUILD)/autogen_display_resources.o + endif endif -ifndef USB_INTERFACE_NAME -USB_INTERFACE_NAME = "CircuitPython" + +USB_INTERFACE_NAME ?= "CircuitPython" + +ifneq ($(USB_VID),) +CFLAGS += -DUSB_VID=$(USB_VID) +CFLAGS += -DSUB_PID=$(USB_PID) +CFLAGS += -DUSB_MANUFACTURER=$(USB_MANUFACTURER) +CFLAGS += -DUSB_PRODUCT=$(USB_PRODUCT) endif # In the following URL, don't include the https:// prefix. # It gets added automatically. -ifndef USB_WEBUSB_URL -USB_WEBUSB_URL = "circuitpython.org" +USB_WEBUSB_URL ?= "circuitpython.org" + +ifeq ($(CIRCUITPY_REPL_USB),1) +USB_DEVICES += CDC endif -USB_DEVICES_COMPUTED := CDC,MSC -ifeq ($(CIRCUITPY_USB_MIDI),1) -USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),AUDIO -endif ifeq ($(CIRCUITPY_USB_HID),1) -USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),HID +USB_DEVICES += HID +endif +ifeq ($(CIRCUITPY_USB_MIDI),1) +USB_DEVICES += AUDIO +endif +ifeq ($(CIRCUITPY_USB_MSC),1) +USB_DEVICES += MSC +endif +ifeq ($(CIRCUITPY_USB_CDC),1) +# Inform TinyUSB there are two CDC devices. +CFLAGS += -DCFG_TUD_CDC=2 +USB_DEVICES += CDC2 endif ifeq ($(CIRCUITPY_USB_VENDOR),1) -USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),VENDOR -endif -USB_DEVICES ?= "$(USB_DEVICES_COMPUTED)" - -ifndef USB_HID_DEVICES -USB_HID_DEVICES = "KEYBOARD,MOUSE,CONSUMER,GAMEPAD" +USB_DEVICES += VENDOR endif -ifndef USB_HIGHSPEED -USB_HIGHSPEED = 0 +USB_HID_DEVICES = +ifeq ($(CIRCUITPY_USB_HID_CONSUMER),1) +USB_HID_DEVICES += CONSUMER +endif +ifeq ($(CIRCUITPY_USB_HID_DIGITIZER),1) +USB_HID_DEVICES += DIGITIZER +endif +ifeq ($(CIRCUITPY_USB_HID_GAMEPAD),1) +USB_HID_DEVICES += GAMEPAD +endif +ifeq ($(CIRCUITPY_USB_HID_KEYBOARD),1) +USB_HID_DEVICES += KEYBOARD +endif +ifeq ($(CIRCUITPY_USB_HID_MOUSE),1) +USB_HID_DEVICES += MOUSE +endif +ifeq ($(CIRCUITPY_USB_HID_SYS_CONTROL),1) +USB_HID_DEVICES += SYS_CONTROL +endif +ifeq ($(CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD),1) +USB_HID_DEVICES += XAC_COMPATIBLE_GAMEPAD endif -ifndef USB_CDC_EP_NUM_NOTIFICATION -USB_CDC_EP_NUM_NOTIFICATION = 0 +# RAW is not compatible with other HID devices. +ifeq ($(CIRCUITPY_USB_HID_RAW),1) + ifneq ($(CIRCUITPY_USB_HID_DEVICES,) + $(error HID RAW must not be combined with other HID devices) +endif +USB_HID_DEVICES += MOUSE endif -ifndef USB_CDC_EP_NUM_DATA_OUT -USB_CDC_EP_NUM_DATA_OUT = 0 -endif +USB_HIGHSPEED ?= 0 -ifndef USB_CDC_EP_NUM_DATA_IN -USB_CDC_EP_NUM_DATA_IN = 0 -endif - -ifndef USB_MSC_EP_NUM_OUT -USB_MSC_EP_NUM_OUT = 0 -endif - -ifndef USB_MSC_EP_NUM_IN -USB_MSC_EP_NUM_IN = 0 -endif - -ifndef USB_HID_EP_NUM_OUT -USB_HID_EP_NUM_OUT = 0 -endif - -ifndef USB_HID_EP_NUM_IN -USB_HID_EP_NUM_IN = 0 -endif - -ifndef USB_MIDI_EP_NUM_OUT -USB_MIDI_EP_NUM_OUT = 0 -endif - -ifndef USB_MIDI_EP_NUM_IN -USB_MIDI_EP_NUM_IN = 0 -endif - -ifndef USB_NUM_EP -USB_NUM_EP = 0 -endif +USB_CDC_EP_NUM_NOTIFICATION ?= 0 +USB_CDC_EP_NUM_DATA_OUT ?= 0 +USB_CDC_EP_NUM_DATA_IN ?= 0 +USB_MSC_EP_NUM_OUT ?= 0 +USB_MSC_EP_NUM_IN ?= 0 +USB_HID_EP_NUM_OUT ?= 0 +USB_HID_EP_NUM_IN ?= 0 +USB_MIDI_EP_NUM_OUT ?= 0 +USB_MIDI_EP_NUM_IN ?= 0 +USB_NUM_EP ?= 0 USB_DESCRIPTOR_ARGS = \ --manufacturer $(USB_MANUFACTURER)\ @@ -197,8 +215,8 @@ USB_DESCRIPTOR_ARGS = \ --pid $(USB_PID)\ --serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\ --interface_name $(USB_INTERFACE_NAME)\ - --devices $(USB_DEVICES)\ - --hid_devices $(USB_HID_DEVICES)\ + --devices "$(USB_DEVICES)"\ + --hid_devices "$(USB_HID_DEVICES)"\ --max_ep $(USB_NUM_EP) \ --cdc_ep_num_notification $(USB_CDC_EP_NUM_NOTIFICATION)\ --cdc_ep_num_data_out $(USB_CDC_EP_NUM_DATA_OUT)\ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-mono-signed.wav new file mode 100644 index 0000000000..cd3da395bd Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-stereo-signed.wav new file mode 100644 index 0000000000..c1036475b8 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-16bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-mono-signed.wav new file mode 100644 index 0000000000..6aa6afc7ab Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-stereo-signed.wav new file mode 100644 index 0000000000..c175aaf612 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-24bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-mono-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-mono-unsigned.wav new file mode 100644 index 0000000000..ccf63b9c15 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-mono-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-stereo-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-stereo-unsigned.wav new file mode 100644 index 0000000000..63aaa5b294 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-16000-8bit-stereo-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-mono-signed.wav new file mode 100644 index 0000000000..147b14b169 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-stereo-signed.wav new file mode 100644 index 0000000000..adfe84fb03 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-mono-signed.wav new file mode 100644 index 0000000000..2c5337045d Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-stereo-signed.wav new file mode 100644 index 0000000000..a290c6c379 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-24bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-mono-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-mono-unsigned.wav new file mode 100644 index 0000000000..cd1c79280a Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-mono-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-stereo-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-stereo-unsigned.wav new file mode 100644 index 0000000000..12c48e2583 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-8bit-stereo-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-stereo.mp3 b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-stereo.mp3 new file mode 100644 index 0000000000..fd820e69ac Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-44100-stereo.mp3 differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-mono-signed.wav new file mode 100644 index 0000000000..a730c2b84c Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-stereo-signed.wav new file mode 100644 index 0000000000..5038ae8ae5 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-mono-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-mono-signed.wav new file mode 100644 index 0000000000..ac25cddb37 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-mono-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-stereo-signed.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-stereo-signed.wav new file mode 100644 index 0000000000..6fec674312 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-24bit-stereo-signed.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-mono-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-mono-unsigned.wav new file mode 100644 index 0000000000..d5e49b24b3 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-mono-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-stereo-unsigned.wav b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-stereo-unsigned.wav new file mode 100644 index 0000000000..3df7945aa2 Binary files /dev/null and b/tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-stereo-unsigned.wav differ diff --git a/tests/circuitpython-manual/audiopwmio/single_buffer_loop.py b/tests/circuitpython-manual/audiopwmio/single_buffer_loop.py new file mode 100644 index 0000000000..dfac475b5b --- /dev/null +++ b/tests/circuitpython-manual/audiopwmio/single_buffer_loop.py @@ -0,0 +1,65 @@ +import audiocore +import audiopwmio +import board +import digitalio +import array +import time +import math + +trigger = digitalio.DigitalInOut(board.D4) +trigger.switch_to_output(True) + +# Generate one period of sine wav. +length = 8000 // 440 + +samples = [] +sample_names = [ +"unsigned 8 bit", +"signed 8 bit", +"unsigned 16 bit", +"signed 16 bit" +] + + +# unsigned 8 bit +u8 = array.array("B", [0] * length) +for i in range(length): + u8[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 7) + 2 ** 7) + +samples.append(audiocore.RawSample(u8, sample_rate=4000)) + +# signed 8 bit +s8 = array.array("b", [0] * length) +for i in range(length): + s8[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 7)) + +samples.append(audiocore.RawSample(s8, sample_rate=16000)) + +# unsigned 16 bit +u16 = array.array("H", [0] * length) +for i in range(length): + u16[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15) + +samples.append(audiocore.RawSample(u16, sample_rate=8000)) + + +# signed 16 bit +s16 = array.array("h", [0] * length) +for i in range(length): + s16[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15)) + +samples.append(audiocore.RawSample(s16, sample_rate=8000)) + + +dac = audiopwmio.PWMAudioOut(board.D13) +for sample, name in zip(samples, sample_names): + print(name) + trigger.value = False + dac.play(sample, loop=True) + time.sleep(1) + dac.stop() + time.sleep(0.1) + trigger.value = True + print() + +print("done") diff --git a/tests/circuitpython-manual/audiopwmio/wavefile_pause_resume.py b/tests/circuitpython-manual/audiopwmio/wavefile_pause_resume.py new file mode 100644 index 0000000000..27912d3217 --- /dev/null +++ b/tests/circuitpython-manual/audiopwmio/wavefile_pause_resume.py @@ -0,0 +1,39 @@ +import audiocore +import audiopwmio +import board +import digitalio +import time +import math +import os + +trigger = digitalio.DigitalInOut(board.D4) +trigger.switch_to_output(True) + +sample_prefix = "jeplayer-splash" + +samples = [] +for fn in os.listdir("/"): + if fn.startswith(sample_prefix): + samples.append(fn) + +dac = audiopwmio.PWMAudioOut(left_channel=board.D12, right_channel=board.D13) +for filename in samples: + print("playing", filename) + with open(filename, "rb") as sample_file: + try: + sample = audiocore.WaveFile(sample_file) + except OSError as e: + print(e) + continue + trigger.value = False + dac.play(sample) + while dac.playing: + time.sleep(0.1) + dac.pause() + time.sleep(0.1) + dac.resume() + trigger.value = True + time.sleep(0.1) + print() + +print("done") diff --git a/tests/circuitpython-manual/audiopwmio/wavefile_playback.py b/tests/circuitpython-manual/audiopwmio/wavefile_playback.py new file mode 100644 index 0000000000..0adbf2b19c --- /dev/null +++ b/tests/circuitpython-manual/audiopwmio/wavefile_playback.py @@ -0,0 +1,36 @@ +import audiocore +import audiopwmio +import board +import digitalio +import time +import math +import os + +trigger = digitalio.DigitalInOut(board.D4) +trigger.switch_to_output(True) + +sample_prefix = "jeplayer-splash" + +samples = [] +for fn in os.listdir("/"): + if fn.startswith(sample_prefix): + samples.append(fn) + +dac = audiopwmio.PWMAudioOut(left_channel=board.D12, right_channel=board.D13) +for filename in samples: + print("playing", filename) + with open(filename, "rb") as sample_file: + try: + sample = audiocore.WaveFile(sample_file) + except OSError as e: + print(e) + continue + trigger.value = False + dac.play(sample) + while dac.playing: + time.sleep(1) + trigger.value = True + time.sleep(0.1) + print() + +print("done") diff --git a/tests/circuitpython-manual/socketpool/client/cpy-client.py b/tests/circuitpython-manual/socketpool/client/cpy-client.py new file mode 100644 index 0000000000..dcc742c9f8 --- /dev/null +++ b/tests/circuitpython-manual/socketpool/client/cpy-client.py @@ -0,0 +1,26 @@ +import wifi +import socketpool +import ssl +import time + +TIMEOUT = None +HOST = '192.168.10.179' +PORT = 5000 + +# Connect to wifi +print("Connecting to wifi") +wifi.radio.connect("mySSID", "myPASS") +pool = socketpool.SocketPool(wifi.radio) + +print("Creating Socket") +with pool.socket(pool.AF_INET, pool.SOCK_STREAM) as s: + s.settimeout(TIMEOUT) + + print("Connecting") + s.connect((HOST, PORT)) + print("Sending") + sent = s.send(b'Hello, world') + print("Receiving") + buff = bytearray(128) + numbytes = s.recv_into(buff) +print(repr(buff)) diff --git a/tests/circuitpython-manual/socketpool/client/host-server.py b/tests/circuitpython-manual/socketpool/client/host-server.py new file mode 100644 index 0000000000..fd7ceb7f14 --- /dev/null +++ b/tests/circuitpython-manual/socketpool/client/host-server.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import socket + +TIMEOUT = 10 +HOST = "192.168.10.179" +PORT = 5000 + +print("Create Socket") +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.settimeout(TIMEOUT) + s.bind((HOST, PORT)) + s.listen() + print("Accepting connections") + while True: + try: + conn, addr = s.accept() + break + except BlockingIOError: + pass + + with conn: + s.settimeout(TIMEOUT) + print('Connected by', addr) + data = conn.recv(128) + print("got: " + str(data)) + conn.sendall(data) + print("sent: " + str(data)) diff --git a/tests/circuitpython-manual/socketpool/client/readme.md b/tests/circuitpython-manual/socketpool/client/readme.md new file mode 100644 index 0000000000..45cdf23c8c --- /dev/null +++ b/tests/circuitpython-manual/socketpool/client/readme.md @@ -0,0 +1,46 @@ +# Circuitpython as Client + +This example demonstrates the use of Socket as a client, accessing a server on a host development machine. This Circuitpython sketch uses the Connect, Send, and Recv_Into methods. + +## Prerequisites + +Circuitpython V6.2.0 minimum. Neither the host or client sketch has installed module prerequisites. + +## Setup + +Find a viable IP address for the host machine first and insert it in both sketches as HOST. On mac, this can be done by going to System Preferences/Network and checking the IP address used to connect to the local wireless network. Make sure that both devices are using the same WIFI! + +Each sketch can have Timeout values changed. The host sketch usually needs a value above 0, or the recv() will fail. Currently, Circuitpython's Connect function is always blocking, so changing the client timeout will not cause much change in behavior. + +Start the Server on the host PC first, within this folder: + +``` +python host-server.py +``` + +Then, reload the client sketch in Circuitpython. + +## Expected Behavior + +The example should connect to a server running on the host machine. The client will send a "Hello world" string to the server, which will return it. + +Expected client output: + +``` +Connecting to wifi +Creating Socket +Connecting +Sending +Receiving +bytearray(b'Hello, world') +``` + +Expected Server output (IP/port values will vary): + +``` +Create Socket +Accepting connections +Connected by ('192.168.10.128', 64509) +got: b'Hello, world' +sent: b'Hello, world' +``` diff --git a/tests/circuitpython-manual/socketpool/datagram/ntp.py b/tests/circuitpython-manual/socketpool/datagram/ntp.py new file mode 100644 index 0000000000..31d922858a --- /dev/null +++ b/tests/circuitpython-manual/socketpool/datagram/ntp.py @@ -0,0 +1,28 @@ +import wifi +import socketpool +import struct +import time + +# connect to wifi +print("Connecting to Wifi") +wifi.radio.connect("mySSID", "myPASS") +pool = socketpool.SocketPool(wifi.radio) + +# make socket +print("Creating socket") +sock = pool.socket(pool.AF_INET,pool.SOCK_DGRAM) + +# Fill packet +packet = bytearray(48) +packet[0] = 0b00100011 # Not leap second, NTP version 4, Client mode +NTP_TO_UNIX_EPOCH = 2208988800 # 1970-01-01 00:00:00 + +print("Sending packet") +sock.sendto(packet, ("pool.ntp.org", 123)) + +size, address = sock.recvfrom_into(packet) +print("Received packet") + +seconds = struct.unpack_from("!I", packet, offset=len(packet) - 8)[0] +print("Address:", address) +print("Time:", time.localtime(seconds - NTP_TO_UNIX_EPOCH)) diff --git a/tests/circuitpython-manual/socketpool/datagram/readme.md b/tests/circuitpython-manual/socketpool/datagram/readme.md new file mode 100644 index 0000000000..f63f0abccd --- /dev/null +++ b/tests/circuitpython-manual/socketpool/datagram/readme.md @@ -0,0 +1,19 @@ +# Circuitpython Datagrams + +This example demonstrates using UDP (datagrams) with the Socket module, accessing the time from an NTP server using `sendto` and `recvfrom_into`. + +## Prerequisites + +Circuitpython V6.2.0 minimum. + +## Expected behavior + +The Circuitpython device will attempt to connect to wifi, and send a request for the time to `pool.ntp.org`. It will then convert the seconds returned into a unix time struct. + +Expected output: +``` +Sending packet +Received packet +Address: ('82.197.188.130', 31488) +Time: struct_time(tm_year=2021, tm_mon=2, tm_mday=11, tm_hour=22, tm_min=22, tm_sec=40, tm_wday=3, tm_yday=42, tm_isdst=-1) +``` diff --git a/tests/circuitpython-manual/socketpool/server/cpy-server.py b/tests/circuitpython-manual/socketpool/server/cpy-server.py new file mode 100644 index 0000000000..d865156bc8 --- /dev/null +++ b/tests/circuitpython-manual/socketpool/server/cpy-server.py @@ -0,0 +1,31 @@ +import wifi +import socketpool + +TIMEOUT = None + +print("Connecting to Wifi") +wifi.radio.connect("mySSID", "myPASS") + +pool = socketpool.SocketPool(wifi.radio) + +print("Finding IP address") +print(wifi.radio.ipv4_address) +HOST = str(wifi.radio.ipv4_address) +PORT = 80 # Port to listen on + +print("Creating socket") +sock = pool.socket(pool.AF_INET,pool.SOCK_STREAM) + +sock.bind((HOST, PORT)) +sock.listen(1) +print("Accepting connections") +conn, addr = sock.accept() +with conn: + print('Connected by', addr) + buff = bytearray(128) + print("Receiving") + numbytes = conn.recvfrom_into(buff) + print(buff[:numbytes[0]]) + if numbytes: + print("Sending") + conn.send(buff[:numbytes[0]]) diff --git a/tests/circuitpython-manual/socketpool/server/host-client.py b/tests/circuitpython-manual/socketpool/server/host-client.py new file mode 100644 index 0000000000..b482755d88 --- /dev/null +++ b/tests/circuitpython-manual/socketpool/server/host-client.py @@ -0,0 +1,17 @@ +import socket + +HOST = '192.168.10.128' # The server's hostname or IP address +PORT = 80 # The port used by the server + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.settimeout(None) + + print("Connecting") + s.connect((HOST, PORT)) + + print("Sending") + s.send(b'Hello, world') + + print("Receiving") + data = s.recv(1024) + print('Received', repr(data)) diff --git a/tests/circuitpython-manual/socketpool/server/readme.md b/tests/circuitpython-manual/socketpool/server/readme.md new file mode 100644 index 0000000000..26118b8f12 --- /dev/null +++ b/tests/circuitpython-manual/socketpool/server/readme.md @@ -0,0 +1,43 @@ +# Circuitpython as Client + +This example demonstrates the use of Socket as a server, accessed by a client program on a host development machine. This Circuitpython sketch uses the Bind, Listen, Accept, and recvfrom_into calls. + +## Prerequisites + +Circuitpython V6.2.0 minimum. Neither the host or client sketch has installed module prerequisites. + +## Setup + +Make sure that both devices are using the same WIFI! The Circuitpython Server will automatically pick an IP and print it over the CDC monitor. Copy this value into the host client sketch. Start the Server on Circuitpython first, then run the client sketch in this folder: + +``` +python host-client.py +``` + +Each sketch can have Timeout values changed. + +## Expected behavior + +The host machine will connect to the server running on the Circuitpython device, and send a "Hello, world" string which is then returned. + +Expected client output: + +``` +Connecting +Sending +Receiving +Received b'Hello, world' +``` + +Expected server output: +``` +Connecting to Wifi +Finding IP address +192.168.10.128 +Creating socket +Accepting connections +Connected by ('192.168.10.179', 33274) +Receiving +bytearray(b'Hello, world') +Sending +``` diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index 80dddeb001..b21cfd920f 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -12,70 +12,130 @@ sys.path.append("../../tools/usb_descriptor") from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util import hid_report_descriptors -DEFAULT_INTERFACE_NAME = 'CircuitPython' -ALL_DEVICES='CDC,MSC,AUDIO,HID,VENDOR' -ALL_DEVICES_SET=frozenset(ALL_DEVICES.split(',')) -DEFAULT_DEVICES='CDC,MSC,AUDIO,HID' +DEFAULT_INTERFACE_NAME = "CircuitPython" +ALL_DEVICES = "CDC CDC2 MSC AUDIO HID VENDOR" +ALL_DEVICES_SET = frozenset(ALL_DEVICES.split()) +DEFAULT_DEVICES = "CDC MSC AUDIO HID" -ALL_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,SYS_CONTROL,GAMEPAD,DIGITIZER,XAC_COMPATIBLE_GAMEPAD,RAW' -ALL_HID_DEVICES_SET=frozenset(ALL_HID_DEVICES.split(',')) +ALL_HID_DEVICES = ( + "KEYBOARD MOUSE CONSUMER SYS_CONTROL GAMEPAD DIGITIZER XAC_COMPATIBLE_GAMEPAD RAW" +) +ALL_HID_DEVICES_SET = frozenset(ALL_HID_DEVICES.split()) # Digitizer works on Linux but conflicts with mouse, so omit it. -DEFAULT_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,GAMEPAD' +DEFAULT_HID_DEVICES = "KEYBOARD MOUSE CONSUMER GAMEPAD" # In the following URL, don't include the https:// because that prefix gets added automatically -DEFAULT_WEBUSB_URL = 'circuitpython.org' # In the future, this may become a specific landing page +DEFAULT_WEBUSB_URL = ( + "circuitpython.org" # In the future, this may become a specific landing page +) -parser = argparse.ArgumentParser(description='Generate USB descriptors.') -parser.add_argument('--highspeed', default=False, action='store_true', - help='descriptor for highspeed device') -parser.add_argument('--manufacturer', type=str, - help='manufacturer of the device') -parser.add_argument('--product', type=str, - help='product name of the device') -parser.add_argument('--vid', type=lambda x: int(x, 16), - help='vendor id') -parser.add_argument('--pid', type=lambda x: int(x, 16), - help='product id') -parser.add_argument('--serial_number_length', type=int, default=32, - help='length needed for the serial number in digits') -parser.add_argument('--devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_DEVICES, - help='devices to include in descriptor (AUDIO includes MIDI support)') -parser.add_argument('--hid_devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_HID_DEVICES, - help='HID devices to include in HID report descriptor') -parser.add_argument('--interface_name', type=str, - help='The name/prefix to use in the interface descriptions', - default=DEFAULT_INTERFACE_NAME) -parser.add_argument('--no-renumber_endpoints', dest='renumber_endpoints', action='store_false', - help='use to not renumber endpoint') -parser.add_argument('--cdc_ep_num_notification', type=int, default=0, - help='endpoint number of CDC NOTIFICATION') -parser.add_argument('--cdc_ep_num_data_out', type=int, default=0, - help='endpoint number of CDC DATA OUT') -parser.add_argument('--cdc_ep_num_data_in', type=int, default=0, - help='endpoint number of CDC DATA IN') -parser.add_argument('--msc_ep_num_out', type=int, default=0, - help='endpoint number of MSC OUT') -parser.add_argument('--msc_ep_num_in', type=int, default=0, - help='endpoint number of MSC IN') -parser.add_argument('--hid_ep_num_out', type=int, default=0, - help='endpoint number of HID OUT') -parser.add_argument('--hid_ep_num_in', type=int, default=0, - help='endpoint number of HID IN') -parser.add_argument('--midi_ep_num_out', type=int, default=0, - help='endpoint number of MIDI OUT') -parser.add_argument('--midi_ep_num_in', type=int, default=0, - help='endpoint number of MIDI IN') -parser.add_argument('--webusb_url', type=str, - help='The URL to include in the WebUSB URL Descriptor', - default=DEFAULT_WEBUSB_URL) -parser.add_argument('--vendor_ep_num_out', type=int, default=0, - help='endpoint number of VENDOR OUT') -parser.add_argument('--vendor_ep_num_in', type=int, default=0, - help='endpoint number of VENDOR IN') -parser.add_argument('--max_ep', type=int, default=0, - help='total number of endpoints available') -parser.add_argument('--output_c_file', type=argparse.FileType('w', encoding='UTF-8'), required=True) -parser.add_argument('--output_h_file', type=argparse.FileType('w', encoding='UTF-8'), required=True) +parser = argparse.ArgumentParser(description="Generate USB descriptors.") +parser.add_argument( + "--highspeed", + default=False, + action="store_true", + help="descriptor for highspeed device", +) +parser.add_argument("--manufacturer", type=str, help="manufacturer of the device") +parser.add_argument("--product", type=str, help="product name of the device") +parser.add_argument("--vid", type=lambda x: int(x, 16), help="vendor id") +parser.add_argument("--pid", type=lambda x: int(x, 16), help="product id") +parser.add_argument( + "--serial_number_length", + type=int, + default=32, + help="length needed for the serial number in digits", +) +parser.add_argument( + "--devices", + type=lambda l: tuple(l.split()), + default=DEFAULT_DEVICES, + help="devices to include in descriptor (AUDIO includes MIDI support)", +) +parser.add_argument( + "--hid_devices", + type=lambda l: tuple(l.split()), + default=DEFAULT_HID_DEVICES, + help="HID devices to include in HID report descriptor", +) +parser.add_argument( + "--interface_name", + type=str, + help="The name/prefix to use in the interface descriptions", + default=DEFAULT_INTERFACE_NAME, +) +parser.add_argument( + "--no-renumber_endpoints", + dest="renumber_endpoints", + action="store_false", + help="use to not renumber endpoint", +) +parser.add_argument( + "--cdc_ep_num_notification", + type=int, + default=0, + help="endpoint number of CDC NOTIFICATION", +) +parser.add_argument( + "--cdc2_ep_num_notification", + type=int, + default=0, + help="endpoint number of CDC2 NOTIFICATION", +) +parser.add_argument( + "--cdc_ep_num_data_out", type=int, default=0, help="endpoint number of CDC DATA OUT" +) +parser.add_argument( + "--cdc_ep_num_data_in", type=int, default=0, help="endpoint number of CDC DATA IN" +) +parser.add_argument( + "--cdc2_ep_num_data_out", + type=int, + default=0, + help="endpoint number of CDC2 DATA OUT", +) +parser.add_argument( + "--cdc2_ep_num_data_in", type=int, default=0, help="endpoint number of CDC2 DATA IN" +) +parser.add_argument( + "--msc_ep_num_out", type=int, default=0, help="endpoint number of MSC OUT" +) +parser.add_argument( + "--msc_ep_num_in", type=int, default=0, help="endpoint number of MSC IN" +) +parser.add_argument( + "--hid_ep_num_out", type=int, default=0, help="endpoint number of HID OUT" +) +parser.add_argument( + "--hid_ep_num_in", type=int, default=0, help="endpoint number of HID IN" +) +parser.add_argument( + "--midi_ep_num_out", type=int, default=0, help="endpoint number of MIDI OUT" +) +parser.add_argument( + "--midi_ep_num_in", type=int, default=0, help="endpoint number of MIDI IN" +) +parser.add_argument( + "--max_ep", type=int, default=0, help="total number of endpoints available" +) +parser.add_argument( + "--webusb_url", + type=str, + help="The URL to include in the WebUSB URL Descriptor", + default=DEFAULT_WEBUSB_URL, +) +parser.add_argument( + "--vendor_ep_num_out", type=int, default=0, help="endpoint number of VENDOR OUT" +) +parser.add_argument( + "--vendor_ep_num_in", type=int, default=0, help="endpoint number of VENDOR IN" +) +parser.add_argument( + "--output_c_file", type=argparse.FileType("w", encoding="UTF-8"), required=True +) +parser.add_argument( + "--output_h_file", type=argparse.FileType("w", encoding="UTF-8"), required=True +) args = parser.parse_args() @@ -87,47 +147,67 @@ unknown_hid_devices = list(frozenset(args.hid_devices) - ALL_HID_DEVICES_SET) if unknown_hid_devices: raise ValueError("Unknown HID devices(s)", unknown_hid_devices) +include_cdc = "CDC" in args.devices +include_cdc2 = "CDC2" in args.devices +include_msc = "MSC" in args.devices +include_hid = "HID" in args.devices +include_audio = "AUDIO" in args.devices +include_vendor = "VENDOR" in args.devices + +if not include_cdc and include_cdc2: + raise ValueError("CDC2 requested without CDC") + if not args.renumber_endpoints: - if 'CDC' in args.devices: + if include_cdc: if args.cdc_ep_num_notification == 0: raise ValueError("CDC notification endpoint number must not be 0") - elif args.cdc_ep_num_data_out == 0: + if args.cdc_ep_num_data_out == 0: raise ValueError("CDC data OUT endpoint number must not be 0") - elif args.cdc_ep_num_data_in == 0: + if args.cdc_ep_num_data_in == 0: raise ValueError("CDC data IN endpoint number must not be 0") - if 'MSC' in args.devices: + if include_cdc2: + if args.cdc2_ep_num_notification == 0: + raise ValueError("CDC2 notification endpoint number must not be 0") + if args.cdc2_ep_num_data_out == 0: + raise ValueError("CDC2 data OUT endpoint number must not be 0") + if args.cdc2_ep_num_data_in == 0: + raise ValueError("CDC2 data IN endpoint number must not be 0") + + if include_msc: if args.msc_ep_num_out == 0: raise ValueError("MSC endpoint OUT number must not be 0") - elif args.msc_ep_num_in == 0: + if args.msc_ep_num_in == 0: raise ValueError("MSC endpoint IN number must not be 0") - if 'HID' in args.devices: + if include_hid: if args.args.hid_ep_num_out == 0: raise ValueError("HID endpoint OUT number must not be 0") - elif args.hid_ep_num_in == 0: + if args.hid_ep_num_in == 0: raise ValueError("HID endpoint IN number must not be 0") - if 'AUDIO' in args.devices: + if include_audio: if args.args.midi_ep_num_out == 0: raise ValueError("MIDI endpoint OUT number must not be 0") - elif args.midi_ep_num_in == 0: + if args.midi_ep_num_in == 0: raise ValueError("MIDI endpoint IN number must not be 0") - if 'VENDOR' in args.devices: + if include_vendor: if args.vendor_ep_num_out == 0: raise ValueError("VENDOR endpoint OUT number must not be 0") - elif args.vendor_ep_num_in == 0: + if args.vendor_ep_num_in == 0: raise ValueError("VENDOR endpoint IN number must not be 0") + class StringIndex: """Assign a monotonically increasing index to each unique string. Start with 0.""" + string_to_index = {} index_to_variable = {} strings = [] @classmethod - def index(cls, string, *, variable_name = None): + def index(cls, string, *, variable_name=None): if string in cls.string_to_index: idx = cls.string_to_index[string] if not cls.index_to_variable[idx]: @@ -145,11 +225,12 @@ class StringIndex: return cls.strings - # langid must be the 0th string descriptor LANGID_INDEX = StringIndex.index("\u0409", variable_name="language_id") assert LANGID_INDEX == 0 -SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length, variable_name="usb_serial_number") +SERIAL_NUMBER_INDEX = StringIndex.index( + "S" * args.serial_number_length, variable_name="usb_serial_number" +) device = standard.DeviceDescriptor( description="top", @@ -157,212 +238,279 @@ device = standard.DeviceDescriptor( idProduct=args.pid, iManufacturer=StringIndex.index(args.manufacturer), iProduct=StringIndex.index(args.product), - iSerialNumber=SERIAL_NUMBER_INDEX) + iSerialNumber=SERIAL_NUMBER_INDEX, +) # Interface numbers are interface-set local and endpoints are interface local # until util.join_interfaces renumbers them. -cdc_union = cdc.Union( - description="CDC comm", - bMasterInterface=0x00, # Adjust this after interfaces are renumbered. - bSlaveInterface_list=[0x01]) # Adjust this after interfaces are renumbered. -cdc_call_management = cdc.CallManagement( - description="CDC comm", - bmCapabilities=0x01, - bDataInterface=0x01) # Adjust this after interfaces are renumbered. - -cdc_comm_interface = standard.InterfaceDescriptor( - description="CDC comm", - bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class - bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, - iInterface=StringIndex.index("{} CDC control".format(args.interface_name)), - subdescriptors=[ - cdc.Header( - description="CDC comm", - bcdCDC=0x0110), - cdc_call_management, - cdc.AbstractControlManagement( - description="CDC comm", - bmCapabilities=0x02), - cdc_union, - standard.EndpointDescriptor( - description="CDC comm in", - bEndpointAddress=args.cdc_ep_num_notification | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - wMaxPacketSize=0x0040, - bInterval=0x10) - ]) - -cdc_data_interface = standard.InterfaceDescriptor( - description="CDC data", - bInterfaceClass=cdc.CDC_CLASS_DATA, - iInterface=StringIndex.index("{} CDC data".format(args.interface_name)), - subdescriptors=[ - standard.EndpointDescriptor( - description="CDC data out", - bEndpointAddress=args.cdc_ep_num_data_out | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0, - wMaxPacketSize=512 if args.highspeed else 64), - standard.EndpointDescriptor( - description="CDC data in", - bEndpointAddress=args.cdc_ep_num_data_in | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0, - wMaxPacketSize=512 if args.highspeed else 64), - ]) - -cdc_interfaces = [cdc_comm_interface, cdc_data_interface] - -msc_interfaces = [ - standard.InterfaceDescriptor( - description="MSC", - bInterfaceClass=msc.MSC_CLASS, - bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, - bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, - iInterface=StringIndex.index("{} Mass Storage".format(args.interface_name)), - subdescriptors=[ - standard.EndpointDescriptor( - description="MSC in", - bEndpointAddress=args.msc_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0, - wMaxPacketSize=512 if args.highspeed else 64), - standard.EndpointDescriptor( - description="MSC out", - bEndpointAddress=(args.msc_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT), - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0, - wMaxPacketSize=512 if args.highspeed else 64), - ] +def make_cdc_union(name): + return cdc.Union( + description="{} comm".format(name), + # Set bMasterInterface and bSlaveInterface_list to proper values after interfaces are renumbered. + bMasterInterface=0x00, + bSlaveInterface_list=[0x01], ) -] -# When there's only one hid_device, it shouldn't have a report id. -# Otherwise, report ids are assigned sequentially: -# args.hid_devices[0] has report_id 1 -# args.hid_devices[1] has report_id 2 -# etc. -report_ids = {} +def make_cdc_call_management(name): + # Set bDataInterface to proper value after interfaces are renumbered. + return cdc.CallManagement( + description="{} comm".format(name), bmCapabilities=0x01, bDataInterface=0x01 + ) -if len(args.hid_devices) == 1: - name = args.hid_devices[0] - combined_hid_report_descriptor = hid.ReportDescriptor( - description=name, - report_descriptor=bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0))) - report_ids[name] = 0 -else: - report_id = 1 - concatenated_descriptors = bytearray() - for name in args.hid_devices: - concatenated_descriptors.extend( - bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id))) - report_ids[name] = report_id - report_id += 1 - combined_hid_report_descriptor = hid.ReportDescriptor( - description="MULTIDEVICE", - report_descriptor=bytes(concatenated_descriptors)) -# ASF4 expects keyboard and generic devices to have both in and out endpoints, -# and will fail (possibly silently) if both are not supplied. -hid_endpoint_in_descriptor = standard.EndpointDescriptor( - description="HID in", - bEndpointAddress=args.hid_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - bInterval=8) - -hid_endpoint_out_descriptor = standard.EndpointDescriptor( - description="HID out", - bEndpointAddress=args.hid_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - bInterval=8) - -hid_interfaces = [ - standard.InterfaceDescriptor( - description="HID Multiple Devices", - bInterfaceClass=hid.HID_CLASS, - bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT, - bInterfaceProtocol=hid.HID_PROTOCOL_NONE, - iInterface=StringIndex.index("{} HID".format(args.interface_name)), +def make_cdc_comm_interface( + name, cdc_union, cdc_call_management, cdc_ep_num_notification +): + return standard.InterfaceDescriptor( + description="{} comm".format(name), + bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE, + iInterface=StringIndex.index("{} {} control".format(args.interface_name, name)), subdescriptors=[ - hid.HIDDescriptor( - description="HID", - wDescriptorLength=len(bytes(combined_hid_report_descriptor))), - hid_endpoint_in_descriptor, - hid_endpoint_out_descriptor, - ] + cdc.Header(description="{} comm".format(name), bcdCDC=0x0110), + cdc_call_management, + cdc.AbstractControlManagement( + description="{} comm".format(name), bmCapabilities=0x02 + ), + cdc_union, + standard.EndpointDescriptor( + description="{} comm in".format(name), + bEndpointAddress=cdc_ep_num_notification + | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + wMaxPacketSize=0x0040, + bInterval=0x10, + ), + ], + ) + + +def make_cdc_data_interface(name, cdc_ep_num_data_in, cdc_ep_num_data_out): + return standard.InterfaceDescriptor( + description="{} data".format(name), + bInterfaceClass=cdc.CDC_CLASS_DATA, + iInterface=StringIndex.index("{} {} data".format(args.interface_name, name)), + subdescriptors=[ + standard.EndpointDescriptor( + description="{} data out".format(name), + bEndpointAddress=cdc_ep_num_data_out + | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + standard.EndpointDescriptor( + description="{} data in".format(name), + bEndpointAddress=cdc_ep_num_data_in + | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + ], + ) + + +if include_cdc: + cdc_union = make_cdc_union("CDC") + cdc_call_management = make_cdc_call_management("CDC") + cdc_comm_interface = make_cdc_comm_interface( + "CDC", cdc_union, cdc_call_management, args.cdc_ep_num_notification + ) + cdc_data_interface = make_cdc_data_interface( + "CDC", args.cdc_ep_num_data_in, args.cdc_ep_num_data_out + ) + + cdc_interfaces = [cdc_comm_interface, cdc_data_interface] + +if include_cdc2: + cdc2_union = make_cdc_union("CDC2") + cdc2_call_management = make_cdc_call_management("CDC2") + cdc2_comm_interface = make_cdc_comm_interface( + "CDC2", cdc2_union, cdc2_call_management, args.cdc2_ep_num_notification + ) + cdc2_data_interface = make_cdc_data_interface( + "CDC2", args.cdc2_ep_num_data_in, args.cdc2_ep_num_data_out + ) + + cdc2_interfaces = [cdc2_comm_interface, cdc2_data_interface] + +if include_msc: + msc_interfaces = [ + standard.InterfaceDescriptor( + description="MSC", + bInterfaceClass=msc.MSC_CLASS, + bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, + bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, + iInterface=StringIndex.index("{} Mass Storage".format(args.interface_name)), + subdescriptors=[ + standard.EndpointDescriptor( + description="MSC in", + bEndpointAddress=args.msc_ep_num_in + | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + standard.EndpointDescriptor( + description="MSC out", + bEndpointAddress=( + args.msc_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT + ), + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + ], + ) + ] + + +if include_hid: + # When there's only one hid_device, it shouldn't have a report id. + # Otherwise, report ids are assigned sequentially: + # args.hid_devices[0] has report_id 1 + # args.hid_devices[1] has report_id 2 + # etc. + + report_ids = {} + + if len(args.hid_devices) == 1: + name = args.hid_devices[0] + combined_hid_report_descriptor = hid.ReportDescriptor( + description=name, + report_descriptor=bytes( + hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0) + ), + ) + report_ids[name] = 0 + else: + report_id = 1 + concatenated_descriptors = bytearray() + for name in args.hid_devices: + concatenated_descriptors.extend( + bytes( + hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id) + ) + ) + report_ids[name] = report_id + report_id += 1 + combined_hid_report_descriptor = hid.ReportDescriptor( + description="MULTIDEVICE", report_descriptor=bytes(concatenated_descriptors) + ) + + # ASF4 expects keyboard and generic devices to have both in and out endpoints, + # and will fail (possibly silently) if both are not supplied. + hid_endpoint_in_descriptor = standard.EndpointDescriptor( + description="HID in", + bEndpointAddress=args.hid_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + bInterval=8, + ) + + hid_endpoint_out_descriptor = standard.EndpointDescriptor( + description="HID out", + bEndpointAddress=args.hid_ep_num_out + | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + bInterval=8, + ) + + hid_interfaces = [ + standard.InterfaceDescriptor( + description="HID Multiple Devices", + bInterfaceClass=hid.HID_CLASS, + bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT, + bInterfaceProtocol=hid.HID_PROTOCOL_NONE, + iInterface=StringIndex.index("{} HID".format(args.interface_name)), + subdescriptors=[ + hid.HIDDescriptor( + description="HID", + wDescriptorLength=len(bytes(combined_hid_report_descriptor)), + ), + hid_endpoint_in_descriptor, + hid_endpoint_out_descriptor, + ], ), ] -# Audio! -# In and out here are relative to CircuitPython +if include_audio: + # Audio! + # In and out here are relative to CircuitPython -# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython -midi_in_jack_emb = midi.InJackDescriptor( - description="MIDI PC -> {}".format(args.interface_name), - bJackType=midi.JACK_TYPE_EMBEDDED, - iJack=StringIndex.index("{} usb_midi.ports[0]".format(args.interface_name))) -midi_out_jack_ext = midi.OutJackDescriptor( - description="MIDI data out to user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, - input_pins=[(midi_in_jack_emb, 1)], - iJack=0) - -# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython -midi_in_jack_ext = midi.InJackDescriptor( - description="MIDI data in from user code.", - bJackType=midi.JACK_TYPE_EXTERNAL, - iJack=0) -midi_out_jack_emb = midi.OutJackDescriptor( - description="MIDI PC <- {}".format(args.interface_name), - bJackType=midi.JACK_TYPE_EMBEDDED, - input_pins=[(midi_in_jack_ext, 1)], - iJack=StringIndex.index("{} usb_midi.ports[1]".format(args.interface_name))) - - -audio_midi_interface = standard.InterfaceDescriptor( - description="Midi goodness", - bInterfaceClass=audio.AUDIO_CLASS_DEVICE, - bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, - bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, - iInterface=StringIndex.index("{} MIDI".format(args.interface_name)), - subdescriptors=[ - midi.Header( - jacks_and_elements=[ - midi_in_jack_emb, - midi_in_jack_ext, - midi_out_jack_emb, - midi_out_jack_ext - ], - ), - standard.EndpointDescriptor( - description="MIDI data out to {}".format(args.interface_name), - bEndpointAddress=args.midi_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=0, - wMaxPacketSize=512 if args.highspeed else 64), - midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]), - standard.EndpointDescriptor( - description="MIDI data in from {}".format(args.interface_name), - bEndpointAddress=args.midi_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval = 0x0, - wMaxPacketSize=512 if args.highspeed else 64), - midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]), - ]) - -cs_ac_interface = audio10.AudioControlInterface( - description="Empty audio control", - audio_streaming_interfaces = [], - midi_streaming_interfaces = [ - audio_midi_interface - ] + # USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython + midi_in_jack_emb = midi.InJackDescriptor( + description="MIDI PC -> {}".format(args.interface_name), + bJackType=midi.JACK_TYPE_EMBEDDED, + iJack=StringIndex.index("{} usb_midi.ports[0]".format(args.interface_name)), + ) + midi_out_jack_ext = midi.OutJackDescriptor( + description="MIDI data out to user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + input_pins=[(midi_in_jack_emb, 1)], + iJack=0, ) -audio_control_interface = standard.InterfaceDescriptor( + # USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython + midi_in_jack_ext = midi.InJackDescriptor( + description="MIDI data in from user code.", + bJackType=midi.JACK_TYPE_EXTERNAL, + iJack=0, + ) + midi_out_jack_emb = midi.OutJackDescriptor( + description="MIDI PC <- {}".format(args.interface_name), + bJackType=midi.JACK_TYPE_EMBEDDED, + input_pins=[(midi_in_jack_ext, 1)], + iJack=StringIndex.index("{} usb_midi.ports[1]".format(args.interface_name)), + ) + + audio_midi_interface = standard.InterfaceDescriptor( + description="Midi goodness", + bInterfaceClass=audio.AUDIO_CLASS_DEVICE, + bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING, + bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1, + iInterface=StringIndex.index("{} MIDI".format(args.interface_name)), + subdescriptors=[ + midi.Header( + jacks_and_elements=[ + midi_in_jack_emb, + midi_in_jack_ext, + midi_out_jack_emb, + midi_out_jack_ext, + ], + ), + standard.EndpointDescriptor( + description="MIDI data out to {}".format(args.interface_name), + bEndpointAddress=args.midi_ep_num_out + | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]), + standard.EndpointDescriptor( + description="MIDI data in from {}".format(args.interface_name), + bEndpointAddress=args.midi_ep_num_in + | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=0x0, + wMaxPacketSize=512 if args.highspeed else 64, + ), + midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]), + ], + ) + + cs_ac_interface = audio10.AudioControlInterface( + description="Empty audio control", + audio_streaming_interfaces=[], + midi_streaming_interfaces=[audio_midi_interface], + ) + + audio_control_interface = standard.InterfaceDescriptor( description="All the audio", bInterfaceClass=audio.AUDIO_CLASS_DEVICE, bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL, @@ -370,89 +518,124 @@ audio_control_interface = standard.InterfaceDescriptor( iInterface=StringIndex.index("{} Audio".format(args.interface_name)), subdescriptors=[ cs_ac_interface, - ]) + ], + ) -# Audio streaming interfaces must occur before MIDI ones. -audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces + # Audio streaming interfaces must occur before MIDI ones. + audio_interfaces = ( + [audio_control_interface] + + cs_ac_interface.audio_streaming_interfaces + + cs_ac_interface.midi_streaming_interfaces + ) -# Vendor-specific interface, for example WebUSB -vendor_endpoint_in_descriptor = standard.EndpointDescriptor( - description="VENDOR in", - bEndpointAddress=args.vendor_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=16) +if include_vendor: + # Vendor-specific interface, for example WebUSB + vendor_endpoint_in_descriptor = standard.EndpointDescriptor( + description="VENDOR in", + bEndpointAddress=args.vendor_ep_num_in + | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=16, + ) -vendor_endpoint_out_descriptor = standard.EndpointDescriptor( - description="VENDOR out", - bEndpointAddress=args.vendor_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT, - bmAttributes=standard.EndpointDescriptor.TYPE_BULK, - bInterval=16) + vendor_endpoint_out_descriptor = standard.EndpointDescriptor( + description="VENDOR out", + bEndpointAddress=args.vendor_ep_num_out + | standard.EndpointDescriptor.DIRECTION_OUT, + bmAttributes=standard.EndpointDescriptor.TYPE_BULK, + bInterval=16, + ) -# We do the following conditionally to avoid adding unused entries to the StringIndex table -if 'VENDOR' in args.devices: vendor_interface = standard.InterfaceDescriptor( description="VENDOR", - bInterfaceClass=0xff, # Vendor-specific + bInterfaceClass=0xFF, # Vendor-specific bInterfaceSubClass=0x00, bInterfaceProtocol=0x00, iInterface=StringIndex.index("{} VENDOR".format(args.interface_name)), subdescriptors=[ vendor_endpoint_in_descriptor, vendor_endpoint_out_descriptor, - ] + ], ) vendor_interfaces = [vendor_interface] interfaces_to_join = [] -if 'CDC' in args.devices: +if include_cdc: interfaces_to_join.append(cdc_interfaces) -if 'MSC' in args.devices: +if include_cdc2: + interfaces_to_join.append(cdc2_interfaces) + +if include_msc: interfaces_to_join.append(msc_interfaces) -if 'HID' in args.devices: +if include_hid: interfaces_to_join.append(hid_interfaces) -if 'AUDIO' in args.devices: +if include_audio: interfaces_to_join.append(audio_interfaces) -if 'VENDOR' in args.devices: +if include_vendor: interfaces_to_join.append(vendor_interfaces) # util.join_interfaces() will renumber the endpoints to make them unique across descriptors, # and renumber the interfaces in order. But we still need to fix up certain # interface cross-references. -interfaces = util.join_interfaces(interfaces_to_join, renumber_endpoints=args.renumber_endpoints) +interfaces = util.join_interfaces( + interfaces_to_join, renumber_endpoints=args.renumber_endpoints +) if args.max_ep != 0: for interface in interfaces: for subdescriptor in interface.subdescriptors: - endpoint_address = getattr(subdescriptor, 'bEndpointAddress', 0) & 0x7f + endpoint_address = getattr(subdescriptor, "bEndpointAddress", 0) & 0x7F if endpoint_address >= args.max_ep: - raise ValueError("Endpoint address %d of %s must be less than %d" % (endpoint_address & 0x7f, interface.description, args.max_ep)) + raise ValueError( + "Endpoint address %d of '%s' must be less than %d; you have probably run out of endpoints" + % (endpoint_address & 0x7F, interface.description, args.max_ep) + ) else: - print("Unable to check whether maximum number of endpoints is respected", file=sys.stderr) + print( + "Unable to check whether maximum number of endpoints is respected", + file=sys.stderr, + ) # Now adjust the CDC interface cross-references. -cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber -cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber] +if include_cdc: + cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber + cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber] -cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber + cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber -cdc_iad = standard.InterfaceAssociationDescriptor( - description="CDC IAD", - bFirstInterface=cdc_comm_interface.bInterfaceNumber, - bInterfaceCount=len(cdc_interfaces), - bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class - bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model - bFunctionProtocol=cdc.CDC_PROTOCOL_NONE) +if include_cdc2: + cdc2_union.bMasterInterface = cdc2_comm_interface.bInterfaceNumber + cdc2_union.bSlaveInterface_list = [cdc2_data_interface.bInterfaceNumber] + + cdc2_call_management.bDataInterface = cdc2_data_interface.bInterfaceNumber + + +def make_cdc_iad(cdc_comm_interface, name): + return standard.InterfaceAssociationDescriptor( + description="{} IAD".format(name), + bFirstInterface=cdc_comm_interface.bInterfaceNumber, + bInterfaceCount=len(cdc_interfaces), + bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bFunctionProtocol=cdc.CDC_PROTOCOL_NONE, + ) + + +if include_cdc: + cdc_iad = make_cdc_iad(cdc_comm_interface, "CDC") +if include_cdc2: + cdc2_iad = make_cdc_iad(cdc2_comm_interface, "CDC2") descriptor_list = [] -if 'CDC' in args.devices: +if include_cdc: # Put the CDC IAD just before the CDC interfaces. # There appears to be a bug in the Windows composite USB driver that requests the # HID report descriptor with the wrong interface number if the HID interface is not given @@ -462,37 +645,47 @@ if 'CDC' in args.devices: descriptor_list.append(cdc_iad) descriptor_list.extend(cdc_interfaces) -if 'MSC' in args.devices: +if include_cdc2: + descriptor_list.append(cdc2_iad) + descriptor_list.extend(cdc2_interfaces) + +if include_msc: descriptor_list.extend(msc_interfaces) -if 'HID' in args.devices: +if include_hid: descriptor_list.extend(hid_interfaces) -if 'AUDIO' in args.devices: +if include_audio: # Only add the control interface because other audio interfaces are managed by it to ensure the # correct ordering. descriptor_list.append(audio_control_interface) -if 'VENDOR' in args.devices: +if include_vendor: descriptor_list.extend(vendor_interfaces) # Finally, build the composite descriptor. configuration = standard.ConfigurationDescriptor( description="Composite configuration", - wTotalLength=(standard.ConfigurationDescriptor.bLength + - sum([len(bytes(x)) for x in descriptor_list])), - bNumInterfaces=len(interfaces)) + wTotalLength=( + standard.ConfigurationDescriptor.bLength + + sum([len(bytes(x)) for x in descriptor_list]) + ), + bNumInterfaces=len(interfaces), +) descriptor_list.insert(0, configuration) -string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()] +string_descriptors = [ + standard.StringDescriptor(string) for string in StringIndex.strings_in_order() +] serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX] c_file = args.output_c_file h_file = args.output_h_file -c_file.write("""\ +c_file.write( + """\ #include #include "tusb.h" @@ -500,34 +693,49 @@ c_file.write("""\ #include "shared-bindings/usb_hid/Device.h" #include "{H_FILE_NAME}" -""".format(H_FILE_NAME=h_file.name)) +""".format( + H_FILE_NAME=h_file.name + ) +) -c_file.write("""\ +c_file.write( + """\ // {DESCRIPTION} : {CLASS} -""".format(DESCRIPTION=device.description, - CLASS=device.__class__)) +""".format( + DESCRIPTION=device.description, CLASS=device.__class__ + ) +) -c_file.write("""\ +c_file.write( + """\ const uint8_t usb_desc_dev[] = { -""") +""" +) for b in bytes(device): c_file.write("0x{:02x}, ".format(b)) -c_file.write("""\ +c_file.write( + """\ }; -""") +""" +) -c_file.write("""\ +c_file.write( + """\ const uint8_t usb_desc_cfg[] = { -""") +""" +) # Write out all the regular descriptors as one long array (that's how ASF4 does it). descriptor_length = 0 for descriptor in descriptor_list: - c_file.write("""\ + c_file.write( + """\ // {DESCRIPTION} : {CLASS} -""".format(DESCRIPTION=descriptor.description, - CLASS=descriptor.__class__)) +""".format( + DESCRIPTION=descriptor.description, CLASS=descriptor.__class__ + ) + ) b = bytes(descriptor) notes = descriptor.notes() @@ -545,17 +753,22 @@ for descriptor in descriptor_list: i += length descriptor_length += len(b) -c_file.write("""\ +c_file.write( + """\ }; -""") +""" +) pointers_to_strings = [] for idx, descriptor in enumerate(string_descriptors): - c_file.write("""\ + c_file.write( + """\ // {DESCRIPTION} : {CLASS} -""".format(DESCRIPTION=descriptor.description, - CLASS=descriptor.__class__)) +""".format( + DESCRIPTION=descriptor.description, CLASS=descriptor.__class__ + ) + ) b = bytes(descriptor) notes = descriptor.notes() @@ -565,45 +778,65 @@ for idx, descriptor in enumerate(string_descriptors): variable_name = StringIndex.index_to_variable[idx] if not variable_name: variable_name = "string_descriptor{}".format(idx) + pointers_to_strings.append("{name}".format(name=variable_name)) const = "const " if variable_name == "usb_serial_number": - const = "" - c_file.write("""\ -{const}uint16_t {NAME}[] = {{ -""".format(const=const, NAME=variable_name)) - pointers_to_strings.append("{name}".format(name=variable_name)) - n = 0 - while i < len(b): - length = b[i] - for j in range(length // 2): - c_file.write("0x{:04x}, ".format(b[i + 2*j + 1] << 8 | b[i + 2*j])) - n += 1 - c_file.write("\n") - i += length - c_file.write("""\ -}; -""") + length = len(b) + c_file.write(" uint16_t {NAME}[{length}];\n".format(NAME=variable_name, length=length//2)) + else: + c_file.write( + """\ + const uint16_t {NAME}[] = {{ + """.format( + const=const, NAME=variable_name + ) + ) + n = 0 + while i < len(b): + length = b[i] + for j in range(length // 2): + c_file.write("0x{:04x}, ".format(b[i + 2 * j + 1] << 8 | b[i + 2 * j])) + n += 1 + c_file.write("\n") + i += length + c_file.write( + """\ + }; + """ + ) -c_file.write("""\ +c_file.write( + """\ // array of pointer to string descriptors uint16_t const * const string_desc_arr [] = { -""") -c_file.write(""",\ +""" +) +c_file.write( + """,\ -""".join(pointers_to_strings)) +""".join( + pointers_to_strings + ) +) -c_file.write(""" +c_file.write( + """ }; -""") +""" +) c_file.write("\n") -hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) +if include_hid: + hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) +else: + hid_descriptor_length = 0 # Now the values we need for the .h file. -h_file.write("""\ +h_file.write( + """\ #ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H #define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H @@ -614,32 +847,43 @@ extern const uint8_t usb_desc_cfg[{configuration_length}]; extern uint16_t usb_serial_number[{serial_number_length}]; extern uint16_t const * const string_desc_arr [{string_descriptor_length}]; -extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}]; - #define CFG_TUSB_RHPORT0_MODE ({rhport0_mode}) -#define USB_HID_NUM_DEVICES {hid_num_devices} - // Vendor name included in Inquiry response, max 8 bytes #define CFG_TUD_MSC_VENDOR "{msc_vendor}" // Product name included in Inquiry response, max 16 bytes #define CFG_TUD_MSC_PRODUCT "{msc_product}" -""" -.format(serial_number_length=len(bytes(serial_number_descriptor)) // 2, +""".format( + serial_number_length=len(bytes(serial_number_descriptor)) // 2, device_length=len(bytes(device)), configuration_length=descriptor_length, max_configuration_length=max(hid_descriptor_length, descriptor_length), string_descriptor_length=len(pointers_to_strings), - hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)), - rhport0_mode='OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED' if args.highspeed else 'OPT_MODE_DEVICE', - hid_num_devices=len(args.hid_devices), + rhport0_mode="OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED" + if args.highspeed + else "OPT_MODE_DEVICE", msc_vendor=args.manufacturer[:8], - msc_product=args.product[:16])) + msc_product=args.product[:16], + ) +) -if 'VENDOR' in args.devices: - h_file.write("""\ +if include_hid: + h_file.write( + """\ +extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}]; + +#define USB_HID_NUM_DEVICES {hid_num_devices} +""".format( + hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)), + hid_num_devices=len(args.hid_devices), + ) + ) + +if include_vendor: + h_file.write( + """\ enum { VENDOR_REQUEST_WEBUSB = 1, @@ -652,43 +896,75 @@ extern uint8_t const desc_ms_os_20[]; // if we try do define this here (TODO figure this out!) //extern const tusb_desc_webusb_url_t desc_webusb_url; -""") +""" + ) -h_file.write("""\ +h_file.write( + """\ #endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H -""") -# Write out the report descriptor and info +""" +) -c_file.write("""\ +if include_hid: + # Write out the report descriptor and info + c_file.write( + """\ const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{ -""".format(HID_DESCRIPTOR_LENGTH=hid_descriptor_length)) +""".format( + HID_DESCRIPTOR_LENGTH=hid_descriptor_length + ) + ) -for b in bytes(combined_hid_report_descriptor): - c_file.write("0x{:02x}, ".format(b)) -c_file.write("""\ + for b in bytes(combined_hid_report_descriptor): + c_file.write("0x{:02x}, ".format(b)) + + c_file.write( + """\ }; -""") +""" + ) -# Write out USB HID report buffer definitions. -for name in args.hid_devices: - c_file.write("""\ + # Write out USB HID report buffer definitions. + for name in args.hid_devices: + c_file.write( + """\ static uint8_t {name}_report_buffer[{report_length}]; -""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length)) +""".format( + name=name.lower(), + report_length=hid_report_descriptors.HID_DEVICE_DATA[ + name + ].report_length, + ) + ) - if hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length > 0: - c_file.write("""\ + if hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length > 0: + c_file.write( + """\ static uint8_t {name}_out_report_buffer[{report_length}]; -""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length)) +""".format( + name=name.lower(), + report_length=hid_report_descriptors.HID_DEVICE_DATA[ + name + ].out_report_length, + ) + ) -# Write out table of device objects. -c_file.write(""" + # Write out table of device objects. + c_file.write( + """\ usb_hid_device_obj_t usb_hid_devices[] = { -""") -for name in args.hid_devices: - device_data = hid_report_descriptors.HID_DEVICE_DATA[name] - out_report_buffer = '{}_out_report_buffer'.format(name.lower()) if device_data.out_report_length > 0 else 'NULL' - c_file.write("""\ +""" + ) + for name in args.hid_devices: + device_data = hid_report_descriptors.HID_DEVICE_DATA[name] + out_report_buffer = ( + "{}_out_report_buffer".format(name.lower()) + if device_data.out_report_length > 0 + else "NULL" + ) + c_file.write( + """\ {{ .base = {{ .type = &usb_hid_device_type }}, .report_buffer = {name}_report_buffer, @@ -699,37 +975,54 @@ for name in args.hid_devices: .out_report_buffer = {out_report_buffer}, .out_report_length = {out_report_length}, }}, -""".format(name=name.lower(), report_id=report_ids[name], - report_length=device_data.report_length, - usage_page=device_data.usage_page, - usage=device_data.usage, - out_report_buffer=out_report_buffer, - out_report_length=device_data.out_report_length)) -c_file.write("""\ +""".format( + name=name.lower(), + report_id=report_ids[name], + report_length=device_data.report_length, + usage_page=device_data.usage_page, + usage=device_data.usage, + out_report_buffer=out_report_buffer, + out_report_length=device_data.out_report_length, + ) + ) + c_file.write( + """\ }; -""") +""" + ) -# Write out tuple of device objects. -c_file.write(""" + # Write out tuple of device objects. + c_file.write( + """ mp_obj_tuple_t common_hal_usb_hid_devices = {{ .base = {{ .type = &mp_type_tuple, }}, .len = {num_devices}, .items = {{ -""".format(num_devices=len(args.hid_devices))) -for idx in range(len(args.hid_devices)): - c_file.write("""\ +""".format( + num_devices=len(args.hid_devices) + ) + ) + for idx in range(len(args.hid_devices)): + c_file.write( + """\ (mp_obj_t) &usb_hid_devices[{idx}], -""".format(idx=idx)) -c_file.write("""\ +""".format( + idx=idx + ) + ) + c_file.write( + """\ }, }; -""") +""" + ) -if 'VENDOR' in args.devices: - # Mimic what the tinyusb webusb demo does in it's main.c file - c_file.write(""" +if include_vendor: + # Mimic what the tinyusb webusb demo does in its main.c file + c_file.write( + """ #define URL "{webusb_url}" const tusb_desc_webusb_url_t desc_webusb_url = @@ -819,4 +1112,8 @@ TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size"); // End of section about desc_ms_os_20 -""".format(webusb_url=args.webusb_url, webusb_interface=vendor_interface.bInterfaceNumber)) +""".format( + webusb_url=args.webusb_url, + webusb_interface=vendor_interface.bInterfaceNumber, + ) + ) diff --git a/tools/usb_descriptor b/tools/usb_descriptor index 701cafc50e..2eaa6114b2 160000 --- a/tools/usb_descriptor +++ b/tools/usb_descriptor @@ -1 +1 @@ -Subproject commit 701cafc50e2e574dccaf7a340eedbd64a0b41a42 +Subproject commit 2eaa6114b209fe7f0a795eda8d6a7b3b93d76d2e