summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/pre-commit.yml4
-rw-r--r--.pre-commit-config.yaml7
-rw-r--r--Makefile2
-rw-r--r--conf.py2
-rw-r--r--docs/robots.txt6
m---------extmod/ulab0
m---------lib/tinyusb0
-rw-r--r--locale/circuitpython.pot25
-rw-r--r--locale/de_DE.po38
-rw-r--r--locale/fr.po12
-rw-r--r--ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/snekboard/mpconfigboard.mk1
-rwxr-xr-xports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/common-hal/pwmio/PWMOut.c7
-rw-r--r--ports/atmel-samd/supervisor/port.c4
-rw-r--r--ports/cxd56/boards/spresense/mpconfigboard.mk2
-rw-r--r--ports/esp32s2/boards/unexpectedmaker_feathers2/board.c8
-rw-r--r--ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h4
-rw-r--r--ports/esp32s2/common-hal/microcontroller/Pin.c45
-rw-r--r--ports/esp32s2/common-hal/microcontroller/Pin.h4
-rw-r--r--ports/esp32s2/common-hal/socketpool/Socket.c7
-rw-r--r--ports/esp32s2/common-hal/wifi/Network.c34
-rw-r--r--ports/esp32s2/mpconfigport.h1
-rw-r--r--ports/nrf/boards/pca10100/mpconfigboard.mk1
-rw-r--r--ports/nrf/boards/simmel/mpconfigboard.mk1
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c12
-rw-r--r--py/circuitpy_defns.mk14
-rw-r--r--py/circuitpy_mpconfig.h8
-rw-r--r--py/circuitpy_mpconfig.mk3
-rw-r--r--shared-bindings/_bleio/Adapter.c14
-rw-r--r--shared-bindings/_pixelbuf/__init__.c2
-rw-r--r--shared-bindings/alarm/SleepMemory.c20
-rw-r--r--shared-bindings/msgpack/ExtType.c126
-rw-r--r--shared-bindings/msgpack/ExtType.h40
-rw-r--r--shared-bindings/msgpack/__init__.c162
-rw-r--r--shared-bindings/msgpack/__init__.h34
-rw-r--r--shared-bindings/wifi/Network.c16
-rw-r--r--shared-bindings/wifi/Network.h1
-rw-r--r--shared-bindings/wifi/Radio.c2
-rw-r--r--shared-module/msgpack/__init__.c464
-rw-r--r--shared-module/msgpack/__init__.h34
-rw-r--r--supervisor/shared/translate.c7
-rw-r--r--tests/extmod/umsgpack_pack.py30
-rw-r--r--tests/extmod/umsgpack_pack.py.ext5
53 files changed, 1163 insertions, 57 deletions
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
index 8caf56d26..af62072c8 100644
--- a/.github/workflows/pre-commit.yml
+++ b/.github/workflows/pre-commit.yml
@@ -15,6 +15,10 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
+ - name: Install deps
+ run: sudo apt-get update && sudo apt-get install -y gettext
+ - name: Populate selected submodules
+ run: git submodule update --init extmod/ulab
- name: set PY
run: echo >>$GITHUB_ENV PY="$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')"
- uses: actions/cache@v1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 322f37da4..82d89eaa3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -11,3 +11,10 @@ repos:
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/esp32s2/esp-idf-config/.*|ports/esp32s2/boards/.*/sdkconfig)'
- id: trailing-whitespace
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)'
+- repo: local
+ hooks:
+ - id: translations
+ name: Check Translations
+ entry: sh -c "make translate"
+ language: system
+ always_run: true
diff --git a/Makefile b/Makefile
index a1807c308..adb206d7b 100644
--- a/Makefile
+++ b/Makefile
@@ -222,7 +222,7 @@ pseudoxml:
all-source:
locale/circuitpython.pot: all-source
- find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=translate -o circuitpython.pot -p locale
+ find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=translate -o - | sed -e '/"POT-Creation-Date: /d' > $@
# Historically, `make translate` updated the .pot file and ran msgmerge.
# However, this was a frequent source of merge conflicts. Weblate can perform
diff --git a/conf.py b/conf.py
index 1a90b617b..590e5bc2c 100644
--- a/conf.py
+++ b/conf.py
@@ -276,7 +276,7 @@ html_static_path = ['docs/static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
-#html_extra_path = []
+html_extra_path = ["docs/robots.txt"]
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
diff --git a/docs/robots.txt b/docs/robots.txt
new file mode 100644
index 000000000..ad3189d42
--- /dev/null
+++ b/docs/robots.txt
@@ -0,0 +1,6 @@
+User-agent: *
+Allow: /*/latest/
+Allow: /en/latest/ # Fallback for bots that don't understand wildcards
+Allow: /*/6.0.x/
+Allow: /en/6.0.x/ # Fallback for bots that don't understand wildcards
+Disallow: /
diff --git a/extmod/ulab b/extmod/ulab
-Subproject c4b06e419f3d515478b05bb8ce03ebdb29cddec
+Subproject d62d07ea0b9597535428ebe6012da6b0d6608bf
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 218b80e63ab6ff87c1851e403f08b3d716d68f5
+Subproject cfcffe94ce62f5ef1fb5aef4641924d64dc4b1c
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index f319b82f8..5d80207b6 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,6 @@ msgid ""
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: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -276,6 +275,10 @@ msgstr ""
msgid "3-arg pow() not supported"
msgstr ""
+#: shared-module/msgpack/__init__.c
+msgid "64 bit types"
+msgstr ""
+
#: 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"
@@ -2426,6 +2429,10 @@ msgstr ""
msgid "circle can only be registered in one parent"
msgstr ""
+#: shared-bindings/msgpack/ExtType.c
+msgid "code outside range 0~127"
+msgstr ""
+
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
msgstr ""
@@ -2510,6 +2517,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr ""
+#: shared-bindings/msgpack/__init__.c
+msgid "default is not a function"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2609,6 +2620,10 @@ msgstr ""
msgid "expecting key:value for dict"
msgstr ""
+#: shared-bindings/msgpack/__init__.c
+msgid "ext_hook is not a function"
+msgstr ""
+
#: py/argcheck.c
msgid "extra keyword arguments given"
msgstr ""
@@ -3141,6 +3156,10 @@ msgstr ""
msgid "no binding for nonlocal found"
msgstr ""
+#: shared-module/msgpack/__init__.c
+msgid "no default packer"
+msgstr ""
+
#: py/builtinimport.c
msgid "no module named '%q'"
msgstr ""
@@ -3474,6 +3493,10 @@ msgstr ""
msgid "shape must be a tuple"
msgstr ""
+#: shared-module/msgpack/__init__.c
+msgid "short read"
+msgstr ""
+
#: py/objstr.c
msgid "sign not allowed in string format specifier"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 0dd711999..a1d072643 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -6,20 +6,22 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
-"PO-Revision-Date: 2020-11-26 03:11+0000\n"
-"Last-Translator: Daniel Bravo Darriba <bravodarriba@gmail.com>\n"
+"PO-Revision-Date: 2021-01-07 18:01+0000\n"
+"Last-Translator: Dennis Schweer <dennis.schweer@ruhr-uni-bochum.de>\n"
"Language: de_DE\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-dev\n"
+"X-Generator: Weblate 4.4.1-dev\n"
#: main.c
msgid ""
"\n"
"Code done running.\n"
msgstr ""
+"\n"
+"Programm wird ausgeführt.\n"
#: main.c
msgid ""
@@ -129,7 +131,7 @@ msgstr "'%q' Objekt unterstützt '%q' nicht"
#: py/obj.c
msgid "'%q' object does not support item assignment"
-msgstr ""
+msgstr "'%q' Objekt unterschützt keine Elementzuweisung"
#: py/obj.c
msgid "'%q' object does not support item deletion"
@@ -141,7 +143,7 @@ msgstr "'%q' Objekt hat kein Attribut '%q'"
#: py/runtime.c
msgid "'%q' object is not an iterator"
-msgstr ""
+msgstr "'%q' Objekt ist kein Iterator"
#: py/objtype.c py/runtime.c
msgid "'%q' object is not callable"
@@ -235,7 +237,7 @@ msgstr "'continue' außerhalb einer Schleife"
#: py/objgenerator.c
msgid "'coroutine' object is not an iterator"
-msgstr ""
+msgstr "'coroutine' Objekt ist kein Iterator"
#: py/compile.c
msgid "'data' requires at least 2 arguments"
@@ -307,7 +309,7 @@ msgstr "Alle I2C-Peripheriegeräte sind in Benutzung"
#: ports/esp32s2/common-hal/frequencyio/FrequencyIn.c
#: ports/esp32s2/common-hal/rotaryio/IncrementalEncoder.c
msgid "All PCNT units in use"
-msgstr ""
+msgstr "Alle PCNT Einheiten sind in Benutzung"
#: ports/atmel-samd/common-hal/canio/Listener.c
#: ports/esp32s2/common-hal/canio/Listener.c
@@ -710,7 +712,7 @@ msgstr "Konnte Kamera nicht initialisieren"
#: ports/cxd56/common-hal/gnss/GNSS.c
msgid "Could not initialize GNSS"
-msgstr ""
+msgstr "GNSS konnte nicht initialisiert werden"
#: ports/cxd56/common-hal/sdioio/SDCard.c
msgid "Could not initialize SDCard"
@@ -837,7 +839,7 @@ msgstr "Die EZB arbeitet jeweils nur mit 16 Bytes"
#: ports/esp32s2/common-hal/busio/SPI.c ports/esp32s2/common-hal/canio/CAN.c
msgid "ESP-IDF memory allocation failed"
-msgstr ""
+msgstr "ESP-IDF Speicherallozierung fehlgeschlagen"
#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c
#: ports/atmel-samd/common-hal/ps2io/Ps2.c
@@ -903,7 +905,7 @@ msgstr "FFT ist nur für ndarrays definiert"
#: extmod/ulab/code/fft/fft.c
msgid "FFT is implemented for linear arrays only"
-msgstr ""
+msgstr "FFT ist nur für lineare Arrays implementiert"
#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Failed SSL handshake"
@@ -934,7 +936,7 @@ msgstr "Konnte keine RX Buffer mit %d allozieren"
#: ports/esp32s2/common-hal/wifi/__init__.c
msgid "Failed to allocate Wifi memory"
-msgstr ""
+msgstr "Zuweisung des Wifi Speichers ist fehlgeschlagen"
#: ports/esp32s2/common-hal/wifi/ScannedNetworks.c
msgid "Failed to allocate wifi scan memory"
@@ -950,7 +952,7 @@ msgstr "Verbindung nicht erfolgreich: timeout"
#: ports/esp32s2/common-hal/wifi/__init__.c
msgid "Failed to init wifi"
-msgstr ""
+msgstr "Wifi Initialisierung ist fehlgeschlagen"
#: shared-module/audiomp3/MP3Decoder.c
msgid "Failed to parse MP3 file"
@@ -1037,7 +1039,7 @@ msgstr "I2SOut nicht verfügbar"
#: 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 & 4 unterstützen keinen internen Pull up im sleep-Modus"
#: shared-bindings/aesio/aes.c
#, c-format
@@ -1058,7 +1060,7 @@ msgstr "Inkorrekte Puffergröße"
#: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c
msgid "Initialization failed due to lack of memory"
-msgstr ""
+msgstr "Initialisierung aufgrund von Speichermangel fehlgeschlagen"
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "Input taking too long"
@@ -3858,7 +3860,7 @@ msgstr "nicht unterstütztes Formatzeichen '%c' (0x%x) bei Index %d"
#: py/runtime.c
msgid "unsupported type for %q: '%q'"
-msgstr ""
+msgstr "nicht unterstützer Typ für %q: '%q'"
#: py/runtime.c
msgid "unsupported type for operator"
@@ -3866,7 +3868,7 @@ msgstr "nicht unterstützter Typ für Operator"
#: py/runtime.c
msgid "unsupported types for %q: '%q', '%q'"
-msgstr ""
+msgstr "nicht unterstützte Typen für %q: '%q', '%q'"
#: py/objint.c
#, c-format
@@ -3911,7 +3913,7 @@ msgstr ""
#: extmod/ulab/code/vector/vectorise.c
msgid "wrong input type"
-msgstr ""
+msgstr "falscher Eingabetyp"
#: extmod/ulab/code/ulab_create.c py/objstr.c
msgid "wrong number of arguments"
@@ -3927,7 +3929,7 @@ msgstr "falscher Operandentyp"
#: extmod/ulab/code/vector/vectorise.c
msgid "wrong output type"
-msgstr ""
+msgstr "Falscher Ausgabetyp"
#: shared-module/displayio/Shape.c
msgid "x value out of bounds"
diff --git a/locale/fr.po b/locale/fr.po
index 187ee6f92..e898631ea 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -8,7 +8,7 @@ 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-01 04:29+0000\n"
+"PO-Revision-Date: 2021-01-07 01:29+0000\n"
"Last-Translator: Hugo Dahl <hugo@code-jedi.com>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
@@ -2595,7 +2595,7 @@ msgstr "les données doivent être de longueur égale"
#: extmod/ulab/code/ndarray.c
msgid "data type not understood"
-msgstr ""
+msgstr "le type de donnée n'est pas reconnu"
#: py/parsenum.c
msgid "decimal numbers not supported"
@@ -2913,7 +2913,7 @@ msgstr "les formes d'entrée et de sortie ne sont pas compatibles"
#: extmod/ulab/code/ulab_create.c
msgid "input argument must be an integer, a tuple, or a list"
-msgstr ""
+msgstr "Paramètre entrant doit être un chiffre entier, un tuple, ou une liste"
#: extmod/ulab/code/fft/fft.c
msgid "input array length must be power of 2"
@@ -3161,7 +3161,7 @@ msgstr "maxiter devrait être > 0"
#: extmod/ulab/code/numerical/numerical.c
msgid "median argument must be an ndarray"
-msgstr ""
+msgstr "Paramètre pour median doit être un ndarray"
#: py/runtime.c
#, c-format
@@ -3745,7 +3745,7 @@ msgstr "trop d'arguments fournis avec ce format"
#: extmod/ulab/code/ulab_create.c
msgid "too many dimensions"
-msgstr ""
+msgstr "Trop de dimensions"
#: extmod/ulab/code/ndarray.c
msgid "too many indices"
@@ -3758,7 +3758,7 @@ msgstr "trop de valeur à dégrouper (%d attendues)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays"
-msgstr ""
+msgstr "trapz est défini pour tableaux à une dimension"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
diff --git a/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk b/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk
index a0d9a779f..cff5a32d1 100644
--- a/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/bdmicro_vina_d21/mpconfigboard.mk
@@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
index 13ec9e861..505f5c145 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
@@ -15,6 +15,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
MICROPY_PY_ASYNC_AWAIT = 0
SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
index 7aa45eb39..c3be33134 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
@@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_PIXELBUF = 1
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
index 3a43093a9..51e9b05af 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
@@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
index 2fe085567..d1a6fc7ae 100644
--- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk
@@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
index 5624144e8..f06163b84 100644
--- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
@@ -18,6 +18,7 @@ CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_GAMEPAD = 0
CFLAGS_INLINE_LIMIT = 50
+CIRCUITPY_MSGPACK = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
index c2d692f9b..3078544fc 100644
--- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk
@@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
# supersized, not ultra-supersized
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
index c35854758..03f633e6d 100644
--- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk
@@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk
index a63f14274..8773c5771 100644
--- a/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/qtpy_m0_haxpress/mpconfigboard.mk
@@ -17,6 +17,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk
index 67e5b2312..889490450 100644
--- a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk
@@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_BITBANGIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
index 590c4795f..5b7f93328 100755
--- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk
@@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk
index 704d26514..734be2d14 100644
--- a/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/stackrduino_m0_pro/mpconfigboard.mk
@@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_COUNTIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BUSDEVICE = 0
diff --git a/ports/atmel-samd/common-hal/pwmio/PWMOut.c b/ports/atmel-samd/common-hal/pwmio/PWMOut.c
index 2e538ccdc..b5142c21e 100644
--- a/ports/atmel-samd/common-hal/pwmio/PWMOut.c
+++ b/ports/atmel-samd/common-hal/pwmio/PWMOut.c
@@ -44,6 +44,7 @@
# define _TCC_SIZE(unused, n) TCC ## n ## _SIZE,
# define TCC_SIZES { REPEAT_MACRO(_TCC_SIZE, 0, TCC_INST_NUM) }
+static const uint8_t tcc_sizes[TCC_INST_NUM] = TCC_SIZES;
static uint32_t tcc_periods[TCC_INST_NUM];
static uint32_t tc_periods[TC_INST_NUM];
@@ -233,8 +234,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
resolution = 16;
} else {
// TCC resolution varies so look it up.
- const uint8_t _tcc_sizes[TCC_INST_NUM] = TCC_SIZES;
- resolution = _tcc_sizes[timer->index];
+ resolution = tcc_sizes[timer->index];
}
// First determine the divisor that gets us the highest resolution.
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
@@ -421,7 +421,8 @@ void common_hal_pwmio_pwmout_set_frequency(pwmio_pwmout_obj_t* self,
if (t->is_tc) {
resolution = 16;
} else {
- resolution = 24;
+ // TCC resolution varies so look it up.
+ resolution = tcc_sizes[t->index];
}
uint32_t system_clock = common_hal_mcu_processor_get_frequency();
uint32_t new_top;
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index b9977fdc4..02b9e3874 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -429,7 +429,9 @@ uint32_t port_get_saved_word(void) {
// TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain
// is enabled.
static volatile uint64_t overflowed_ticks = 0;
+#ifdef SAMD21
static volatile bool _ticks_enabled = false;
+#endif
static uint32_t _get_count(uint64_t* overflow_count) {
#ifdef SAM_D5X_E5X
@@ -537,9 +539,11 @@ void port_disable_tick(void) {
// they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting
// the next RTC wake up time.
void port_interrupt_after_ticks(uint32_t ticks) {
+ #ifdef SAMD21
if (_ticks_enabled) {
return;
}
+ #endif
_port_interrupt_after_ticks(ticks);
}
diff --git a/ports/cxd56/boards/spresense/mpconfigboard.mk b/ports/cxd56/boards/spresense/mpconfigboard.mk
index 7b8ac6ff6..80c6e4b69 100644
--- a/ports/cxd56/boards/spresense/mpconfigboard.mk
+++ b/ports/cxd56/boards/spresense/mpconfigboard.mk
@@ -4,3 +4,5 @@ USB_PRODUCT = "Spresense"
USB_MANUFACTURER = "Sony"
INTERNAL_FLASH_FILESYSTEM = 1
+
+CIRCUITPY_MSGPACK = 0
diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/board.c b/ports/esp32s2/boards/unexpectedmaker_feathers2/board.c
index d8fd3a0a2..ac08190a5 100644
--- a/ports/esp32s2/boards/unexpectedmaker_feathers2/board.c
+++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/board.c
@@ -27,6 +27,8 @@
#include "supervisor/board.h"
#include "mpconfigboard.h"
#include "shared-bindings/microcontroller/Pin.h"
+#include "components/driver/include/driver/gpio.h"
+#include "components/soc/include/hal/gpio_hal.h"
void board_init(void) {
// USB
@@ -47,6 +49,12 @@ void board_init(void) {
common_hal_never_reset_pin(&pin_GPIO30);
common_hal_never_reset_pin(&pin_GPIO31);
common_hal_never_reset_pin(&pin_GPIO32);
+
+
+ // Add LDO2 to never reset list, set to output and enable
+ common_hal_never_reset_pin(&pin_GPIO21);
+ gpio_set_direction(pin_GPIO21.number, GPIO_MODE_DEF_OUTPUT);
+ gpio_set_level(pin_GPIO21.number, true);
}
bool board_requests_safe_mode(void) {
diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h
index e100ac118..6b1a0c4aa 100644
--- a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h
+++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h
@@ -34,8 +34,8 @@
#define AUTORESET_DELAY_MS 500
-// #define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
-// #define MICROPY_HW_APA102_SCK (&pin_GPIO45)
+#define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
+#define MICROPY_HW_APA102_SCK (&pin_GPIO45)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8)
diff --git a/ports/esp32s2/common-hal/microcontroller/Pin.c b/ports/esp32s2/common-hal/microcontroller/Pin.c
index fca89ce8e..6889720e8 100644
--- a/ports/esp32s2/common-hal/microcontroller/Pin.c
+++ b/ports/esp32s2/common-hal/microcontroller/Pin.c
@@ -37,13 +37,14 @@
#ifdef MICROPY_HW_NEOPIXEL
bool neopixel_in_use;
#endif
+#ifdef MICROPY_HW_APA102_MOSI
+bool apa102_sck_in_use;
+bool apa102_mosi_in_use;
+#endif
STATIC uint32_t never_reset_pins[2];
STATIC uint32_t in_use[2];
-bool apa102_mosi_in_use;
-bool apa102_sck_in_use;
-
STATIC void floating_gpio_reset(gpio_num_t pin_number) {
// This is the same as gpio_reset_pin(), but without the pullup.
// Note that gpio_config resets the iomatrix to GPIO_FUNC as well.
@@ -86,6 +87,20 @@ void reset_pin_number(gpio_num_t pin_number) {
return;
}
#endif
+ #ifdef MICROPY_HW_APA102_MOSI
+ if (pin_number == MICROPY_HW_APA102_MOSI->number ||
+ pin_number == MICROPY_HW_APA102_SCK->number) {
+ apa102_mosi_in_use = apa102_mosi_in_use && pin_number != MICROPY_HW_APA102_MOSI->number;
+ apa102_sck_in_use = apa102_sck_in_use && pin_number != MICROPY_HW_APA102_SCK->number;
+ if (!apa102_sck_in_use && !apa102_mosi_in_use) {
+ rgb_led_status_init();
+ }
+ return;
+ }
+ #endif
+
+
+
}
void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
@@ -110,6 +125,11 @@ void reset_all_pins(void) {
#ifdef MICROPY_HW_NEOPIXEL
neopixel_in_use = false;
#endif
+ #ifdef MICROPY_HW_APA102_MOSI
+ apa102_sck_in_use = false;
+ apa102_mosi_in_use = false;
+ #endif
+
}
void claim_pin(const mcu_pin_obj_t* pin) {
@@ -119,6 +139,15 @@ void claim_pin(const mcu_pin_obj_t* pin) {
neopixel_in_use = true;
}
#endif
+ #ifdef MICROPY_HW_APA102_MOSI
+ if (pin == MICROPY_HW_APA102_MOSI) {
+ apa102_mosi_in_use = true;
+ }
+ if (pin == MICROPY_HW_APA102_SCK) {
+ apa102_sck_in_use = true;
+ }
+ #endif
+
}
void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) {
@@ -131,10 +160,18 @@ bool pin_number_is_free(gpio_num_t pin_number) {
return !neopixel_in_use;
}
#endif
+ #ifdef MICROPY_HW_APA102_MOSI
+ if (pin_number == MICROPY_HW_APA102_MOSI->number) {
+ return !apa102_mosi_in_use;
+ }
+ if (pin_number == MICROPY_HW_APA102_SCK->number) {
+ return !apa102_sck_in_use;
+ }
+ #endif
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/microcontroller/Pin.h b/ports/esp32s2/common-hal/microcontroller/Pin.h
index f6c008703..65f57a82d 100644
--- a/ports/esp32s2/common-hal/microcontroller/Pin.h
+++ b/ports/esp32s2/common-hal/microcontroller/Pin.h
@@ -31,8 +31,10 @@
#include "peripherals/pins.h"
-extern bool apa102_mosi_in_use;
+#ifdef MICROPY_HW_APA102_MOSI
extern bool apa102_sck_in_use;
+extern bool apa102_mosi_in_use;
+#endif
#ifdef MICROPY_HW_NEOPIXEL
extern bool neopixel_in_use;
diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c
index 32c5fc72f..5e943f8fd 100644
--- a/ports/esp32s2/common-hal/socketpool/Socket.c
+++ b/ports/esp32s2/common-hal/socketpool/Socket.c
@@ -178,7 +178,7 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* se
struct sockaddr_in source_addr;
socklen_t socklen = sizeof(source_addr);
- int bytes_received = lwip_recvfrom(self->num, buf, len - 1, 0, (struct sockaddr *)&source_addr, &socklen);
+ int bytes_received = lwip_recvfrom(self->num, buf, len, 0, (struct sockaddr *)&source_addr, &socklen);
memcpy((void *)ip, (void*)&source_addr.sin_addr.s_addr, sizeof source_addr.sin_addr.s_addr);
*port = source_addr.sin_port;
@@ -186,10 +186,9 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t* se
if (bytes_received < 0) {
mp_raise_BrokenPipeError();
return 0;
- } else {
- buf[bytes_received] = 0; // Null-terminate whatever we received
- return bytes_received;
}
+
+ return bytes_received;
}
void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) {
diff --git a/ports/esp32s2/common-hal/wifi/Network.c b/ports/esp32s2/common-hal/wifi/Network.c
index 2674df065..b6eb6bb43 100644
--- a/ports/esp32s2/common-hal/wifi/Network.c
+++ b/ports/esp32s2/common-hal/wifi/Network.c
@@ -54,3 +54,37 @@ mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self) {
// 2 instead of strlen(cstr) as this gives us only the country-code
return mp_obj_new_str(cstr, 2);
}
+
+mp_obj_t common_hal_wifi_network_get_authmode(wifi_network_obj_t *self) {
+ const char* authmode = "";
+ switch (self->record.authmode) {
+ case WIFI_AUTH_OPEN:
+ authmode = "OPEN";
+ break;
+ case WIFI_AUTH_WEP:
+ authmode = "WEP";
+ break;
+ case WIFI_AUTH_WPA_PSK:
+ authmode = "WPA_PSK";
+ break;
+ case WIFI_AUTH_WPA2_PSK:
+ authmode = "WPA2_PSK";
+ break;
+ case WIFI_AUTH_WPA_WPA2_PSK:
+ authmode = "WPA_WPA2_PSK";
+ break;
+ case WIFI_AUTH_WPA2_ENTERPRISE:
+ authmode = "WPA2_ENTERPRISE";
+ break;
+ case WIFI_AUTH_WPA3_PSK:
+ authmode = "WPA3_PSK";
+ break;
+ case WIFI_AUTH_WPA2_WPA3_PSK:
+ authmode = "WPA2_WPA3_PSK";
+ break;
+ default:
+ authmode = "UNKNOWN";
+ break;
+ }
+ return mp_obj_new_str(authmode, strlen(authmode));
+}
diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h
index db7393d8e..9c0fd9da3 100644
--- a/ports/esp32s2/mpconfigport.h
+++ b/ports/esp32s2/mpconfigport.h
@@ -32,6 +32,7 @@
#define MICROPY_PY_UJSON (1)
#define MICROPY_USE_INTERNAL_PRINTF (0)
+#define MICROPY_PY_SYS_PLATFORM "Espressif ESP32-S2"
#include "py/circuitpy_mpconfig.h"
diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk
index 86ba65454..76d15e608 100644
--- a/ports/nrf/boards/pca10100/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10100/mpconfigboard.mk
@@ -15,6 +15,7 @@ CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FRAMEBUFFERIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_NVM = 0
CIRCUITPY_PIXELBUF = 0
diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk
index dd6b1fbfd..4eb6c98c7 100644
--- a/ports/nrf/boards/simmel/mpconfigboard.mk
+++ b/ports/nrf/boards/simmel/mpconfigboard.mk
@@ -16,6 +16,7 @@ CIRCUITPY_AUDIOMP3 = 0
CIRCUITPY_BUSIO = 1
CIRCUITPY_DISPLAYIO = 0
CIRCUITPY_FRAMEBUFFERIO = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_GAMEPAD = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_NVM = 0
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index 53a40f9a6..10794c16a 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -469,7 +469,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
ble_drv_add_event_handler(scan_on_ble_evt, self->scan_results);
- uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS);
+ uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS) + 0.5f;
if (nrf_timeout > UINT16_MAX) {
// 0xffff / 100
mp_raise_ValueError(translate("timeout must be < 655.35 secs"));
@@ -479,15 +479,15 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
mp_raise_ValueError(translate("non-zero timeout must be > 0.01"));
}
- if (nrf_timeout) {
+ if (nrf_timeout == 0) {
nrf_timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED;
}
ble_gap_scan_params_t scan_params = {
.extended = extended,
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS) + 0.5f,
.timeout = nrf_timeout,
- .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
+ .window = SEC_TO_UNITS(window, UNIT_0_625_MS) + 0.5f,
.scan_phys = BLE_GAP_PHY_1MBPS,
.active = active
};
@@ -553,7 +553,7 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
.window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
.scan_phys = BLE_GAP_PHY_1MBPS,
// timeout of 0 means no timeout
- .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
+ .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS) + 0.5f,
};
ble_gap_conn_params_t conn_params = {
@@ -696,7 +696,7 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
}
ble_gap_adv_params_t adv_params = {
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS) + 0.5f,
.properties.type = adv_type,
.duration = SEC_TO_UNITS(timeout, UNIT_10_MS),
.filter_policy = BLE_GAP_ADV_FP_ANY,
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index d6d192a95..21bd5b965 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -58,6 +58,14 @@ BASE_CFLAGS = \
# -H
+# Set a global CIRCUITPY_DEBUG flag.
+# Don't just call it "DEBUG": too many libraries use plain DEBUG.
+ifneq ($(DEBUG),)
+CFLAGS += -DCIRCUITPY_DEBUG=$(DEBUG)
+else
+CFLAGS += -DCIRCUITPY_DEBUG=0
+endif
+
###
# Handle frozen modules.
@@ -292,6 +300,9 @@ endif
ifeq ($(CIRCUITPY_PEW),1)
SRC_PATTERNS += _pew/%
endif
+ifeq ($(CIRCUITPY_MSGPACK),1)
+SRC_PATTERNS += msgpack/%
+endif
# All possible sources are listed here, and are filtered by SRC_PATTERNS in SRC_COMMON_HAL
SRC_COMMON_HAL_ALL = \
@@ -412,6 +423,8 @@ $(filter $(SRC_PATTERNS), \
math/__init__.c \
microcontroller/ResetReason.c \
microcontroller/RunMode.c \
+ msgpack/__init__.c \
+ msgpack/ExtType.c \
supervisor/RunReason.c \
)
@@ -481,6 +494,7 @@ SRC_SHARED_MODULE_ALL = \
memorymonitor/AllocationAlarm.c \
memorymonitor/AllocationSize.c \
network/__init__.c \
+ msgpack/__init__.c \
os/__init__.c \
random/__init__.c \
rgbmatrix/RGBMatrix.c \
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index 08c92a77e..a3411b7ad 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -774,6 +774,13 @@ extern const struct _mp_obj_module_t wifi_module;
#define WIFI_MODULE
#endif
+#if CIRCUITPY_MSGPACK
+extern const struct _mp_obj_module_t msgpack_module;
+#define MSGPACK_MODULE { MP_ROM_QSTR(MP_QSTR_msgpack), MP_ROM_PTR(&msgpack_module) },
+#else
+#define MSGPACK_MODULE
+#endif
+
// Define certain native modules with weak links so they can be replaced with Python
// implementations. This list may grow over time.
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
@@ -830,6 +837,7 @@ extern const struct _mp_obj_module_t wifi_module;
_EVE_MODULE \
MEMORYMONITOR_MODULE \
MICROCONTROLLER_MODULE \
+ MSGPACK_MODULE \
NEOPIXEL_WRITE_MODULE \
NETWORK_MODULE \
SOCKET_MODULE \
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index e588c41e0..a01da2956 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -308,3 +308,6 @@ 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/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index 7d7076aab..81277fd70 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -33,8 +33,8 @@
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Adapter.h"
-#define ADV_INTERVAL_MIN (0.02001f)
-#define ADV_INTERVAL_MIN_STRING "0.02001"
+#define ADV_INTERVAL_MIN (0.02f)
+#define ADV_INTERVAL_MIN_STRING "0.02"
#define ADV_INTERVAL_MAX (10.24f)
#define ADV_INTERVAL_MAX_STRING "10.24"
// 20ms is recommended by Apple
@@ -204,7 +204,7 @@ const mp_obj_property_t bleio_adapter_name_obj = {
//| :param ~_typing.ReadableBuffer scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
//| :param bool anonymous: If `True` then this device's MAC address is randomized before advertising.
-//| :param int timeout: If set, we will only advertise for this many seconds.
+//| :param int timeout: If set, we will only advertise for this many seconds. Zero means no timeout.
//| :param float interval: advertising interval, in seconds"""
//| ...
//|
@@ -237,7 +237,7 @@ STATIC mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t
args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT);
}
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ const mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj);
if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
@@ -279,7 +279,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapt
//| ignored. Format is one byte for length (n) and n bytes of prefix and can be repeated.
//| :param int buffer_size: the maximum number of advertising bytes to buffer.
//| :param bool extended: When True, support extended advertising packets. Increasing buffer_size is recommended when this is set.
-//| :param float timeout: the scan timeout in seconds. If None, will scan until `stop_scan` is called.
+//| :param float timeout: the scan timeout in seconds. If None or zero, will scan until `stop_scan` is called.
//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
//| Must be in the range 0.0025 - 40.959375 seconds.
//| :param float window: the duration (in seconds) to scan a single BLE channel.
@@ -320,7 +320,7 @@ STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args
args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
}
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ const mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj);
if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
}
@@ -332,7 +332,7 @@ STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args
}
#pragma GCC diagnostic pop
- const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
+ const mp_float_t window = mp_obj_get_float(args[ARG_window].u_obj);
if (window > interval) {
mp_raise_ValueError(translate("window must be <= interval"));
}
diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c
index c61acc939..fdd02509c 100644
--- a/shared-bindings/_pixelbuf/__init__.c
+++ b/shared-bindings/_pixelbuf/__init__.c
@@ -51,7 +51,7 @@
//|
STATIC mp_obj_t pixelbuf_colorwheel(mp_obj_t n) {
- return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_float_get(n)));
+ return MP_OBJ_NEW_SMALL_INT(colorwheel(MP_OBJ_IS_SMALL_INT(n) ? MP_OBJ_SMALL_INT_VALUE(n) : mp_obj_get_float(n)));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_colorwheel_obj, pixelbuf_colorwheel);
diff --git a/shared-bindings/alarm/SleepMemory.c b/shared-bindings/alarm/SleepMemory.c
index bec0b7665..aed24827a 100644
--- a/shared-bindings/alarm/SleepMemory.c
+++ b/shared-bindings/alarm/SleepMemory.c
@@ -53,6 +53,25 @@
//| """Not used. Access the sole instance through `alarm.sleep_memory`."""
//| ...
//|
+//| def __bool__(self) -> bool:
+//| """``sleep_memory`` is ``True`` if its length is greater than zero.
+//| This is an easy way to check for its existence.
+//| """
+//| ...
+//|
+//| def __len__(self) -> int:
+//| """Return the length. This is used by (`len`)"""
+//| ...
+//|
+STATIC mp_obj_t alarm_sleep_memory_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ alarm_sleep_memory_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ uint16_t len = common_hal_alarm_sleep_memory_get_length(self);
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
+ case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
STATIC const mp_rom_map_elem_t alarm_sleep_memory_locals_dict_table[] = {
};
@@ -154,6 +173,7 @@ const mp_obj_type_t alarm_sleep_memory_type = {
{ &mp_type_type },
.name = MP_QSTR_SleepMemory,
.subscr = alarm_sleep_memory_subscr,
+ .unary_op = alarm_sleep_memory_unary_op,
.print = NULL,
.locals_dict = (mp_obj_t)&alarm_sleep_memory_locals_dict,
};
diff --git a/shared-bindings/msgpack/ExtType.c b/shared-bindings/msgpack/ExtType.c
new file mode 100644
index 000000000..e9ddd32bc
--- /dev/null
+++ b/shared-bindings/msgpack/ExtType.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Bernhard Boser
+ *
+ * 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/runtime.h"
+#include "py/smallint.h"
+#include "py/objproperty.h"
+#include "shared-bindings/msgpack/ExtType.h"
+
+//| class ExtType:
+//| """ExtType represents ext type in msgpack."""
+//| def __init__(self, code: int, data: bytes) -> None:
+//| """Constructor
+//| :param int code: type code in range 0~127.
+//| :param bytes data: representation."""
+//|
+STATIC mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mod_msgpack_extype_obj_t *self = m_new_obj(mod_msgpack_extype_obj_t);
+ self->base.type = &mod_msgpack_exttype_type;
+ enum { ARG_code, ARG_data };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_code, MP_ARG_INT | MP_ARG_REQUIRED },
+ { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ };
+ 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 code = args[ARG_code].u_int;
+ if (code < 0 || code > 127) {
+ mp_raise_AttributeError(translate("code outside range 0~127"));
+ }
+ self->code = code;
+
+ mp_obj_t data = args[ARG_data].u_obj;
+ self->data = data;
+ return MP_OBJ_FROM_PTR(self);
+}
+
+
+//| code: int
+//| """The type code, in range 0~127."""
+//| ...
+//|
+STATIC mp_obj_t mod_msgpack_exttype_get_code(mp_obj_t self_in) {
+ mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return MP_OBJ_NEW_SMALL_INT(self->code);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mod_msgpack_exttype_get_code_obj, mod_msgpack_exttype_get_code);
+
+STATIC mp_obj_t mod_msgpack_exttype_set_code(mp_obj_t self_in, mp_obj_t code_in) {
+ mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ int code = mp_obj_get_int(code_in);
+ if (code < 0 || code > 127) {
+ mp_raise_AttributeError(translate("code outside range 0~127"));
+ }
+ self->code = code;
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(mod_msgpack_exttype_set_code_obj, mod_msgpack_exttype_set_code);
+
+const mp_obj_property_t mod_msgpack_exttype_code_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&mod_msgpack_exttype_get_code_obj,
+ (mp_obj_t)&mod_msgpack_exttype_set_code_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| data: bytes
+//| """Data."""
+//| ...
+//|
+STATIC mp_obj_t mod_msgpack_exttype_get_data(mp_obj_t self_in) {
+ mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return self->data;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mod_msgpack_exttype_get_data_obj, mod_msgpack_exttype_get_data);
+
+STATIC mp_obj_t mod_msgpack_exttype_set_data(mp_obj_t self_in, mp_obj_t data_in) {
+ mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ self->data = data_in;
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(mod_msgpack_exttype_set_data_obj, mod_msgpack_exttype_set_data);
+
+const mp_obj_property_t mod_msgpack_exttype_data_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&mod_msgpack_exttype_get_data_obj,
+ (mp_obj_t)&mod_msgpack_exttype_set_data_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC mp_rom_map_elem_t mod_msgpack_exttype_locals_dict_table[] = {
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_code), MP_ROM_PTR(&mod_msgpack_exttype_code_obj) },
+ { MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&mod_msgpack_exttype_data_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(mod_msgpack_exttype_locals_dict, mod_msgpack_exttype_locals_dict_table);
+
+const mp_obj_type_t mod_msgpack_exttype_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_ExtType,
+ .make_new = mod_msgpack_exttype_make_new,
+ .locals_dict = (mp_obj_dict_t*)&mod_msgpack_exttype_locals_dict,
+};
diff --git a/shared-bindings/msgpack/ExtType.h b/shared-bindings/msgpack/ExtType.h
new file mode 100644
index 000000000..64173b221
--- /dev/null
+++ b/shared-bindings/msgpack/ExtType.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Bernhard Boser
+ *
+ * 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_MSGPACK_EXTTYPE___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK_EXTTYPE___INIT___H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ int32_t code;
+ mp_obj_t data;
+} mod_msgpack_extype_obj_t;
+
+extern const mp_obj_type_t mod_msgpack_exttype_type;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK_EXTTYPE___INIT___H
diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c
new file mode 100644
index 000000000..f5c47bb21
--- /dev/null
+++ b/shared-bindings/msgpack/__init__.c
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Bernhard Boser
+ *
+ * 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 <stdio.h>
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "shared-bindings/msgpack/__init__.h"
+#include "shared-module/msgpack/__init__.h"
+#include "shared-bindings/msgpack/ExtType.h"
+
+#define MP_OBJ_IS_METH(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_bound_method))
+
+//| """Pack object in msgpack format
+//|
+//| The msgpack format is similar to json, except that the encoded data is binary.
+//| See https://msgpack.org for details. The module implements a subset of the cpython
+//| module msgpack-python.
+//|
+//| Not implemented: 64-bit int, uint, float.
+//|
+//| Example 1::
+//|
+//| import msgpack
+//| from io import BytesIO
+//|
+//| b = BytesIO()
+//| msgpack.pack({'list': [True, False, None, 1, 3.14], 'str': 'blah'}, b)
+//| b.seek(0)
+//| print(msgpack.unpack(b))
+//|
+//| Example 2: handling objects::
+//|
+//| from msgpack import pack, unpack, ExtType
+//| from io import BytesIO
+//|
+//| class MyClass:
+//| def __init__(self, val):
+//| self.value = val
+//| def __str__(self):
+//| return str(self.value)
+//|
+//| data = MyClass(b'my_value')
+//|
+//| def encoder(obj):
+//| if isinstance(obj, MyClass):
+//| return ExtType(1, obj.value)
+//| return f"no encoder for {obj}"
+//|
+//| def decoder(code, data):
+//| if code == 1:
+//| return MyClass(data)
+//| return f"no decoder for type {code}"
+//|
+//| buffer = BytesIO()
+//| pack(data, buffer, default=encoder)
+//| buffer.seek(0)
+//| decoded = unpack(buffer, ext_hook=decoder)
+//| print(f"{data} -> {buffer.getvalue()} -> {decoded}")
+//|
+//| """
+//|
+
+//| def pack(obj: object, buffer: WriteableBuffer, *, default: Union[Callable[[object], None], None] = None) -> None:
+//| """Ouput object to buffer in msgpack format.
+//|
+//| :param object obj: Object to convert to msgpack format.
+//| :param ~_typing.WriteableBuffer buffer: buffer to write into
+//| :param Optional[~_typing.Callable[[object], None]] default:
+//| function called for python objects that do not have
+//| a representation in msgpack format.
+//| """
+//| ...
+//|
+STATIC mp_obj_t mod_msgpack_pack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_obj, ARG_buffer, ARG_default };
+ STATIC const mp_arg_t allowed_args[] = {
+ { MP_QSTR_obj, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_default, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t handler = args[ARG_default].u_obj;
+ if (handler != mp_const_none && !MP_OBJ_IS_FUN(handler) && !MP_OBJ_IS_METH(handler)) {
+ mp_raise_ValueError(translate("default is not a function"));
+ }
+
+ common_hal_msgpack_pack(args[ARG_obj].u_obj, args[ARG_buffer].u_obj, handler);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_pack_obj, 1, mod_msgpack_pack);
+
+
+//| def unpack(buffer: ReadableBuffer, *, ext_hook: Union[Callable[[int, bytes], object], None] = None, use_list: bool=True) -> object:
+//| """Unpack and return one object from buffer.
+//|
+//| :param ~_typing.ReadableBuffer buffer: buffer to read from
+//| :param Optional[~_typing.Callable[[int, bytes], object]] ext_hook: function called for objects in
+//| msgpack ext format.
+//| :param Optional[bool] use_list: return array as list or tuple (use_list=False).
+//|
+//| :return object: object read from buffer.
+//| """
+//| ...
+//|
+STATIC mp_obj_t mod_msgpack_unpack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_buffer, ARG_ext_hook, ARG_use_list };
+ STATIC const mp_arg_t allowed_args[] = {
+ { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, },
+ { MP_QSTR_ext_hook, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
+ { MP_QSTR_use_list, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = true } },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t hook = args[ARG_ext_hook].u_obj;
+ if (hook != mp_const_none && !MP_OBJ_IS_FUN(hook) && !MP_OBJ_IS_METH(hook)) {
+ mp_raise_ValueError(translate("ext_hook is not a function"));
+ }
+
+ return common_hal_msgpack_unpack(args[ARG_buffer].u_obj, hook, args[ARG_use_list].u_bool);
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_unpack_obj, 1, mod_msgpack_unpack);
+
+
+STATIC const mp_rom_map_elem_t msgpack_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_msgpack) },
+ { MP_ROM_QSTR(MP_QSTR_ExtType), MP_ROM_PTR(&mod_msgpack_exttype_type) },
+ { MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&mod_msgpack_pack_obj) },
+ { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&mod_msgpack_unpack_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(msgpack_module_globals, msgpack_module_globals_table);
+
+const mp_obj_module_t msgpack_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&msgpack_module_globals,
+};
diff --git a/shared-bindings/msgpack/__init__.h b/shared-bindings/msgpack/__init__.h
new file mode 100644
index 000000000..a02ead0bd
--- /dev/null
+++ b/shared-bindings/msgpack/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
+
+#include "py/obj.h"
+
+// nothing for now
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
diff --git a/shared-bindings/wifi/Network.c b/shared-bindings/wifi/Network.c
index 009712ad1..0f3006f2e 100644
--- a/shared-bindings/wifi/Network.c
+++ b/shared-bindings/wifi/Network.c
@@ -124,6 +124,21 @@ const mp_obj_property_t wifi_network_country_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| authmode: str
+//| """String id of the authmode"""
+//|
+STATIC mp_obj_t wifi_network_get_authmode(mp_obj_t self) {
+ return common_hal_wifi_network_get_authmode(self);
+
+}
+MP_DEFINE_CONST_FUN_OBJ_1(wifi_network_get_authmode_obj, wifi_network_get_authmode);
+
+const mp_obj_property_t wifi_network_authmode_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&wifi_network_get_authmode_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
STATIC const mp_rom_map_elem_t wifi_network_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&wifi_network_ssid_obj) },
@@ -131,6 +146,7 @@ STATIC const mp_rom_map_elem_t wifi_network_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&wifi_network_rssi_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&wifi_network_channel_obj) },
{ MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&wifi_network_country_obj) },
+ { MP_ROM_QSTR(MP_QSTR_authmode), MP_ROM_PTR(&wifi_network_authmode_obj) },
};
STATIC MP_DEFINE_CONST_DICT(wifi_network_locals_dict, wifi_network_locals_dict_table);
diff --git a/shared-bindings/wifi/Network.h b/shared-bindings/wifi/Network.h
index e672e3108..0f07e7b55 100644
--- a/shared-bindings/wifi/Network.h
+++ b/shared-bindings/wifi/Network.h
@@ -40,5 +40,6 @@ extern mp_obj_t common_hal_wifi_network_get_bssid(wifi_network_obj_t *self);
extern mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self);
extern mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self);
extern mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self);
+extern mp_obj_t common_hal_wifi_network_get_authmode(wifi_network_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_WIFI_NETWORK_H
diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c
index 723572a32..63f507067 100644
--- a/shared-bindings/wifi/Radio.c
+++ b/shared-bindings/wifi/Radio.c
@@ -295,7 +295,7 @@ const mp_obj_property_t wifi_radio_ipv4_dns_obj = {
};
//| ap_info: Optional[Network]
-//| """Network object containing BSSID, SSID, channel, country and RSSI when connected to an access point. None otherwise."""
+//| """Network object containing BSSID, SSID, authmode, channel, country and RSSI when connected to an access point. None otherwise."""
//|
STATIC mp_obj_t wifi_radio_get_ap_info(mp_obj_t self) {
return common_hal_wifi_radio_get_ap_info(self);
diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c
new file mode 100644
index 000000000..39178d46e
--- /dev/null
+++ b/shared-module/msgpack/__init__.c
@@ -0,0 +1,464 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Bernhard Boser
+ *
+ * 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 <stdio.h>
+#include <inttypes.h>
+
+#include "py/obj.h"
+#include "py/binary.h"
+#include "py/objarray.h"
+#include "py/objlist.h"
+#include "py/objstringio.h"
+#include "py/parsenum.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "supervisor/shared/translate.h"
+#include "shared-bindings/msgpack/ExtType.h"
+
+////////////////////////////////////////////////////////////////
+// stream management
+
+typedef struct _msgpack_stream_t {
+ mp_obj_t stream_obj;
+ mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
+ mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
+ int errcode;
+} msgpack_stream_t;
+
+STATIC msgpack_stream_t get_stream(mp_obj_t stream_obj, int flags) {
+ const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, flags);
+ msgpack_stream_t s = {stream_obj, stream_p->read, stream_p->write, 0};
+ return s;
+}
+
+////////////////////////////////////////////////////////////////
+// readers
+
+STATIC void read(msgpack_stream_t *s, void *buf, mp_uint_t size) {
+ if (size == 0) return;
+ mp_uint_t ret = s->read(s->stream_obj, buf, size, &s->errcode);
+ if (s->errcode != 0) {
+ mp_raise_OSError(s->errcode);
+ }
+ if (ret == 0) {
+ mp_raise_msg(&mp_type_EOFError, NULL);
+ }
+ if (ret < size) {
+ mp_raise_ValueError(translate("short read"));
+ }
+}
+
+STATIC uint8_t read1(msgpack_stream_t *s) {
+ uint8_t res = 0;
+ read(s, &res, 1);
+ return res;
+}
+
+STATIC uint16_t read2(msgpack_stream_t *s) {
+ uint16_t res = 0;
+ read(s, &res, 2);
+ int n = 1;
+ if (*(char *)&n == 1) res = __builtin_bswap16(res);
+ return res;
+}
+
+STATIC uint32_t read4(msgpack_stream_t *s) {
+ uint32_t res = 0;
+ read(s, &res, 4);
+ int n = 1;
+ if (*(char *)&n == 1) res = __builtin_bswap32(res);
+ return res;
+}
+
+STATIC size_t read_size(msgpack_stream_t *s, uint8_t len_index) {
+ size_t res = 0;
+ switch (len_index) {
+ case 0: res = (size_t)read1(s); break;
+ case 1: res = (size_t)read2(s); break;
+ case 2: res = (size_t)read4(s); break;
+ }
+ return res;
+}
+
+////////////////////////////////////////////////////////////////
+// writers
+
+STATIC void write(msgpack_stream_t *s, const void *buf, mp_uint_t size) {
+ mp_uint_t ret = s->write(s->stream_obj, buf, size, &s->errcode);
+ if (s->errcode != 0) {
+ mp_raise_OSError(s->errcode);
+ }
+ if (ret == 0) {
+ mp_raise_msg(&mp_type_EOFError, NULL);
+ }
+}
+
+STATIC void write1(msgpack_stream_t *s, uint8_t obj) {
+ write(s, &obj, 1);
+}
+
+STATIC void write2(msgpack_stream_t *s, uint16_t obj) {
+ int n = 1;
+ if (*(char *)&n == 1) obj = __builtin_bswap16(obj);
+ write(s, &obj, 2);
+}
+
+STATIC void write4(msgpack_stream_t *s, uint32_t obj) {
+ int n = 1;
+ if (*(char *)&n == 1) obj = __builtin_bswap32(obj);
+ write(s, &obj, 4);
+}
+
+// compute and write msgpack size code (array structures)
+STATIC void write_size(msgpack_stream_t *s, uint8_t code, size_t size) {
+ if ((uint8_t)size == size) {
+ write1(s, code);
+ write1(s, size);
+ } else if ((uint16_t)size == size) {
+ write1(s, code+1);
+ write2(s, size);
+ } else {
+ write1(s, code+2);
+ write4(s, size);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// packers
+
+// This is a helper function to iterate through a dictionary. The state of
+// the iteration is held in *cur and should be initialised with zero for the
+// first call. Will return NULL when no more elements are available.
+STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) {
+ size_t max = dict->map.alloc;
+ mp_map_t *map = &dict->map;
+
+ for (size_t i = *cur; i < max; i++) {
+ if (MP_MAP_SLOT_IS_FILLED(map, i)) {
+ *cur = i + 1;
+ return &(map->table[i]);
+ }
+ }
+
+ return NULL;
+}
+
+STATIC void pack_int(msgpack_stream_t *s, int32_t x) {
+ if (x > -32 && x < 128) {
+ write1(s, x);
+ } else if ((int8_t)x == x) {
+ write1(s, 0xd0);
+ write1(s, x);
+ } else if ((int16_t)x == x) {
+ write1(s, 0xd1);
+ write2(s, x);
+ } else {
+ write1(s, 0xd2);
+ write4(s, x);
+ }
+}
+
+STATIC void pack_bin(msgpack_stream_t *s, const uint8_t* data, size_t len) {
+ write_size(s, 0xc4, len);
+ if (len > 0) write(s, data, len);
+}
+
+STATIC void pack_ext(msgpack_stream_t *s, int8_t code, const uint8_t* data, size_t len) {
+ if (len == 1) {
+ write1(s, 0xd4);
+ } else if (len == 2) {
+ write1(s, 0xd5);
+ } else if (len == 4) {
+ write1(s, 0xd6);
+ } else if (len == 8) {
+ write1(s, 0xd7);
+ } else if (len == 16) {
+ write1(s, 0xd8);
+ } else {
+ write_size(s, 0xc7, len);
+ }
+ write1(s, code); // type byte
+ if (len > 0) write(s, data, len);
+}
+
+STATIC void pack_str(msgpack_stream_t *s, const char* str, size_t len) {
+ if (len < 32) {
+ write1(s, 0b10100000 | (uint8_t)len);
+ } else {
+ write_size(s, 0xd9, len);
+ }
+ if (len > 0) write(s, str, len);
+}
+
+STATIC void pack_array(msgpack_stream_t *s, size_t len) {
+ // only writes the header, manually write the objects after calling pack_array!
+ if (len < 16) {
+ write1(s, 0b10010000 | (uint8_t)len);
+ } else if (len < 0x10000) {
+ write1(s, 0xdc);
+ write2(s, len);
+ } else {
+ write1(s, 0xdd);
+ write4(s, len);
+ }
+}
+
+STATIC void pack_dict(msgpack_stream_t *s, size_t len) {
+ // only writes the header, manually write the objects after calling pack_array!
+ if (len < 16) {
+ write1(s, 0b10000000 | (uint8_t)len);
+ } else if (len < 0x10000) {
+ write1(s, 0xde);
+ write2(s, len);
+ } else {
+ write1(s, 0xdf);
+ write4(s, len);
+ }
+}
+
+STATIC void pack(mp_obj_t obj, msgpack_stream_t *s, mp_obj_t default_handler) {
+ if (MP_OBJ_IS_SMALL_INT(obj)) {
+ // int
+ int32_t x = MP_OBJ_SMALL_INT_VALUE(obj);
+ pack_int(s, x);
+ } else if (MP_OBJ_IS_STR(obj)) {
+ // string
+ size_t len;
+ const char *data = mp_obj_str_get_data(obj, &len);
+ pack_str(s, data, len);
+ } else if (MP_OBJ_IS_TYPE(obj, &mod_msgpack_exttype_type)) {
+ mod_msgpack_extype_obj_t *ext = MP_OBJ_TO_PTR(obj);
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(ext->data, &bufinfo, MP_BUFFER_READ);
+ pack_ext(s, ext->code, bufinfo.buf, bufinfo.len);
+ } else if (MP_OBJ_IS_TYPE(obj, &mp_type_bytes)) {
+ // bytes
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
+ pack_bin(s, bufinfo.buf, bufinfo.len);
+ } else if (MP_OBJ_IS_TYPE(obj, &mp_type_tuple)) {
+ // tuple
+ mp_obj_tuple_t *self = MP_OBJ_TO_PTR(obj);
+ pack_array(s, self->len);
+ for (size_t i=0; i<self->len; i++) {
+ pack(self->items[i], s, default_handler);
+ }
+ } else if (MP_OBJ_IS_TYPE(obj, &mp_type_list)) {
+ // list (layout differs from tuple)
+ mp_obj_list_t *self = MP_OBJ_TO_PTR(obj);
+ pack_array(s, self->len);
+ for (size_t i=0; i<self->len; i++) {
+ pack(self->items[i], s, default_handler);
+ }
+ } else if (MP_OBJ_IS_TYPE(obj, &mp_type_dict)) {
+ // dict
+ mp_obj_dict_t *self = MP_OBJ_TO_PTR(obj);
+ pack_dict(s, self->map.used);
+ size_t cur = 0;
+ mp_map_elem_t *next = NULL;
+ while ((next = dict_iter_next(self, &cur)) != NULL) {
+ pack(next->key, s, default_handler);
+ pack(next->value, s, default_handler);
+ }
+ } else if (mp_obj_is_float(obj)) {
+ union Float { mp_float_t f; uint32_t u; };
+ union Float data;
+ data.f = mp_obj_float_get(obj);
+ write1(s, 0xca);
+ write4(s, data.u);
+ } else if (obj == mp_const_none) {
+ write1(s, 0xc0);
+ } else if (obj == mp_const_false) {
+ write1(s, 0xc2);
+ } else if (obj == mp_const_true) {
+ write1(s, 0xc3);
+ } else {
+ if (default_handler != mp_const_none) {
+ // set default_handler to mp_const_none to avoid infinite recursion
+ // this also precludes some valid outputs
+ pack(mp_call_function_1(default_handler, obj), s, mp_const_none);
+ } else {
+ mp_raise_ValueError(translate("no default packer"));
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// unpacker
+
+STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list);
+
+STATIC mp_obj_t unpack_array_elements(msgpack_stream_t *s, size_t size, mp_obj_t ext_hook, bool use_list) {
+ if (use_list) {
+ mp_obj_list_t *t = MP_OBJ_TO_PTR(mp_obj_new_list(size, NULL));
+ for (size_t i=0; i<size; i++) {
+ t->items[i] = unpack(s, ext_hook, use_list);
+ }
+ return MP_OBJ_FROM_PTR(t);
+ } else {
+ mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(size, NULL));
+ for (size_t i=0; i<size; i++) {
+ t->items[i] = unpack(s, ext_hook, use_list);
+ }
+ return MP_OBJ_FROM_PTR(t);
+ }
+}
+
+STATIC mp_obj_t unpack_bytes(msgpack_stream_t *s, size_t size) {
+ vstr_t vstr;
+ vstr_init_len(&vstr, size);
+ byte *p = (byte*)vstr.buf;
+ read(s, p, size);
+ return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
+}
+
+STATIC mp_obj_t unpack_ext(msgpack_stream_t *s, size_t size, mp_obj_t ext_hook) {
+ int8_t code = read1(s);
+ mp_obj_t data = unpack_bytes(s, size);
+ if (ext_hook != mp_const_none) {
+ return mp_call_function_2(ext_hook, MP_OBJ_NEW_SMALL_INT(code), data);
+ } else {
+ mod_msgpack_extype_obj_t *o = m_new_obj(mod_msgpack_extype_obj_t);
+ o->base.type = &mod_msgpack_exttype_type;
+ o->code = code;
+ o->data = data;
+ return MP_OBJ_FROM_PTR(o);
+ }
+}
+
+STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) {
+ uint8_t code = read1(s);
+ if (((code & 0b10000000) == 0) || ((code & 0b11100000) == 0b11100000)) {
+ // int
+ return MP_OBJ_NEW_SMALL_INT((int8_t)code);
+ }
+ if ((code & 0b11100000) == 0b10100000) {
+ // str
+ size_t len = code & 0b11111;
+ // allocate on stack; len < 32
+ char str[len];
+ read(s, &str, len);
+ return mp_obj_new_str(str, len);
+ }
+ if ((code & 0b11110000) == 0b10010000) {
+ // array (list / tuple)
+ return unpack_array_elements(s, code & 0b1111, ext_hook, use_list);
+ }
+ if ((code & 0b11110000) == 0b10000000) {
+ // map (dict)
+ size_t len = code & 0b1111;
+ mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len));
+ for (size_t i=0; i<len; i++) {
+ mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list));
+ }
+ return MP_OBJ_FROM_PTR(d);
+ }
+ switch (code) {
+ case 0xc0: return mp_const_none;
+ case 0xc2: return mp_const_false;
+ case 0xc3: return mp_const_true;
+ case 0xc4:
+ case 0xc5:
+ case 0xc6: {
+ // bin 8, 16, 32
+ return unpack_bytes(s, read_size(s, code-0xc4));
+ }
+ case 0xcc: // uint8
+ case 0xd0: // int8
+ return MP_OBJ_NEW_SMALL_INT((int8_t)read1(s));
+ case 0xcd: // uint16
+ case 0xd1: // int16
+ return MP_OBJ_NEW_SMALL_INT((int16_t)read2(s));
+ case 0xce: // uint32
+ case 0xd2: // int32
+ return MP_OBJ_NEW_SMALL_INT((int32_t)read4(s));
+ case 0xca: {
+ union Float { mp_float_t f; uint32_t u; };
+ union Float data;
+ data.u = read4(s);
+ return mp_obj_new_float(data.f);
+ }
+ case 0xd9:
+ case 0xda:
+ case 0xdb: {
+ // str 8, 16, 32
+ size_t size = read_size(s, code-0xd9);
+ vstr_t vstr;
+ vstr_init_len(&vstr, size);
+ byte *p = (byte*)vstr.buf;
+ read(s, p, size);
+ return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
+ }
+ case 0xde:
+ case 0xdf: {
+ // map 16 & 32
+ size_t len = read_size(s, code - 0xde + 1);
+ mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len));
+ for (size_t i=0; i<len; i++) {
+ mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list));
+ }
+ return MP_OBJ_FROM_PTR(d);
+ }
+ case 0xdc:
+ case 0xdd: {
+ // array 16 & 32
+ size_t size = read_size(s, code - 0xdc + 1);
+ return unpack_array_elements(s, size, ext_hook, use_list);
+ }
+ case 0xd4: // fixenxt 1
+ return unpack_ext(s, 1, ext_hook);
+ case 0xd5: // fixenxt 2
+ return unpack_ext(s, 2, ext_hook);
+ case 0xd6: // fixenxt 4
+ return unpack_ext(s, 4, ext_hook);
+ case 0xd7: // fixenxt 8
+ return unpack_ext(s, 8, ext_hook);
+ case 0xd8: // fixenxt 16
+ return unpack_ext(s, 16, ext_hook);
+ case 0xc7: // ext 8
+ case 0xc8: // ext 16
+ case 0xc9:
+ // ext 8, 16, 32
+ return unpack_ext(s, read_size(s, code-0xc7), ext_hook);
+ case 0xc1: // never used
+ case 0xcb: // float 64
+ case 0xcf: // uint 64
+ case 0xd3: // int 64
+ default:
+ mp_raise_NotImplementedError(translate("64 bit types"));
+ }
+}
+
+void common_hal_msgpack_pack(mp_obj_t obj, mp_obj_t stream_obj, mp_obj_t default_handler) {
+ msgpack_stream_t stream = get_stream(stream_obj, MP_STREAM_OP_WRITE);
+ pack(obj, &stream, default_handler);
+}
+
+mp_obj_t common_hal_msgpack_unpack(mp_obj_t stream_obj, mp_obj_t ext_hook, bool use_list) {
+ msgpack_stream_t stream = get_stream(stream_obj, MP_STREAM_OP_WRITE);
+ return unpack(&stream, ext_hook, use_list);
+}
diff --git a/shared-module/msgpack/__init__.h b/shared-module/msgpack/__init__.h
new file mode 100644
index 000000000..88b4809f9
--- /dev/null
+++ b/shared-module/msgpack/__init__.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_MSGPACK___INIT___H
+#define MICROPY_INCLUDED_SHARED_MODULE_MSGPACK___INIT___H
+
+#include "py/stream.h"
+
+void common_hal_msgpack_pack(mp_obj_t obj, mp_obj_t stream_obj, mp_obj_t default_handler);
+mp_obj_t common_hal_msgpack_unpack(mp_obj_t stream_obj, mp_obj_t ext_hook, bool use_list);
+
+#endif
diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c
index 44544c98d..8bd3c5acd 100644
--- a/supervisor/shared/translate.c
+++ b/supervisor/shared/translate.c
@@ -122,7 +122,12 @@ char* decompress(const compressed_string_t* compressed, char* decompressed) {
return decompressed;
}
-inline __attribute__((always_inline)) const compressed_string_t* translate(const char* original) {
+inline
+// gcc10 -flto has issues with this being always_inline for debug builds.
+#if CIRCUITPY_DEBUG < 1
+ __attribute__((always_inline))
+#endif
+const compressed_string_t* translate(const char* original) {
#ifndef NO_QSTR
#define QDEF(id, str)
#define TRANSLATION(id, firstbyte, ...) if (strcmp(original, id) == 0) { static const compressed_string_t v = { .data = firstbyte, .tail = { __VA_ARGS__ } }; return &v; } else
diff --git a/tests/extmod/umsgpack_pack.py b/tests/extmod/umsgpack_pack.py
new file mode 100644
index 000000000..d9f0005e1
--- /dev/null
+++ b/tests/extmod/umsgpack_pack.py
@@ -0,0 +1,30 @@
+try:
+ from uio import BytesIO
+ import umsgpack as msgpack
+except:
+ try:
+ from io import BytesIO
+ import msgpack
+ except ImportError:
+ print("SKIP")
+ raise SystemExit
+
+b = BytesIO()
+msgpack.pack(False, s)
+print(b.getvalue())
+
+b = BytesIO()
+msgpack.pack({"a": (-1, 0, 2, [3, None], 128)}, b)
+print(b.getvalue())
+
+# pack to a small-int not allowed
+try:
+ msgpack.pack(123, 1)
+except (AttributeError, OSError): # CPython and uPy have different errors
+ print('Exception')
+
+# pack to an object not allowed
+try:
+ msgpack.pack(123, {})
+except (AttributeError, OSError): # CPython and uPy have different errors
+ print('Exception')
diff --git a/tests/extmod/umsgpack_pack.py.ext b/tests/extmod/umsgpack_pack.py.ext
new file mode 100644
index 000000000..2f966be06
--- /dev/null
+++ b/tests/extmod/umsgpack_pack.py.ext
@@ -0,0 +1,5 @@
+b'\xc2'
+b'\x82\xa1a\x96\xff\x00\x02\x92\x03\xc0\xd1\x00\x80\xc4\x07abcdefg\xa1b\xd4\x05x'
+Exception ExtType
+Exception to int
+Exception to object