summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Boser <boser@berkeley.edu>2021-01-27 09:22:41 -0800
committerBernhard Boser <boser@berkeley.edu>2021-01-27 09:22:41 -0800
commite285b5b98ca24c877b794f1a4e019693c130b1bc (patch)
tree4d4d5c420e9e5a56b7ae1d196438e4694b298642
parent16d54586c1b5cbf839ee8fbb78cf56dd105096f3 (diff)
parent45b3c9ae4213008da092d5bb35e8602e1e90bca2 (diff)
Merge remote-tracking branch 'adafruit/main' into cp-flow
-rw-r--r--.github/workflows/build.yml5
-rw-r--r--.gitmodules3
-rw-r--r--Makefile1
-rw-r--r--README.rst2
-rw-r--r--conf.py1
-rw-r--r--docs/design_guide.rst4
-rw-r--r--docs/library/errno.rst (renamed from docs/library/uerrno.rst)10
-rw-r--r--docs/library/esp.rst85
-rw-r--r--docs/library/index.rst53
-rw-r--r--docs/library/io.rst (renamed from docs/library/uio.rst)6
-rw-r--r--docs/library/json.rst (renamed from docs/library/ujson.rst)6
-rw-r--r--docs/library/network.rst278
-rw-r--r--docs/library/re.rst (renamed from docs/library/ure.rst)8
-rw-r--r--docs/shared_bindings_matrix.py4
-rw-r--r--docs/supported_ports.rst3
-rw-r--r--extmod/vfs.c5
m---------lib/protomatter0
m---------lib/tinyusb0
-rw-r--r--locale/ID.po105
-rw-r--r--locale/circuitpython.pot44
-rw-r--r--locale/cs.po45
-rw-r--r--locale/de_DE.po45
-rw-r--r--locale/el.po45
-rw-r--r--locale/es.po50
-rw-r--r--locale/fil.po45
-rw-r--r--locale/fr.po56
-rw-r--r--locale/hi.po45
-rw-r--r--locale/it_IT.po45
-rw-r--r--locale/ja.po45
-rw-r--r--locale/ko.po45
-rw-r--r--locale/nl.po50
-rw-r--r--locale/pl.po59
-rw-r--r--locale/pt_BR.po54
-rw-r--r--locale/sv.po98
-rw-r--r--locale/zh_Latn_pinyin.po228
-rwxr-xr-xmain.c9
-rw-r--r--ports/atmel-samd/boards/8086_commander/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk2
-rwxr-xr-xports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk3
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/boards/pycubed/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk10
-rw-r--r--ports/atmel-samd/boards/sam32/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/serpente/mpconfigboard.mk1
-rwxr-xr-xports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk6
-rw-r--r--ports/atmel-samd/boards/ugame10/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk1
-rw-r--r--ports/atmel-samd/mpconfigport.h7
-rw-r--r--ports/atmel-samd/mpconfigport.mk52
-rw-r--r--ports/cxd56/README.md2
-rw-r--r--ports/cxd56/configs/circuitpython/defconfig1
m---------ports/cxd56/spresense-exported-sdk0
-rw-r--r--ports/cxd56/supervisor/internal_flash.c16
-rw-r--r--ports/esp32s2/common-hal/displayio/ParallelBus.c175
-rw-r--r--ports/esp32s2/common-hal/displayio/ParallelBus.h11
-rw-r--r--ports/esp32s2/common-hal/socketpool/Socket.c302
-rw-r--r--ports/esp32s2/common-hal/socketpool/Socket.h8
-rw-r--r--ports/esp32s2/common-hal/socketpool/SocketPool.c29
-rw-r--r--ports/esp32s2/common-hal/wifi/Radio.c27
-rw-r--r--ports/esp32s2/mpconfigport.h1
-rw-r--r--ports/esp32s2/peripherals/touch.c7
-rw-r--r--ports/esp32s2/supervisor/port.c7
-rw-r--r--ports/litex/mpconfigport.h2
-rw-r--r--ports/mimxrt10xx/mpconfigport.h2
-rw-r--r--ports/nrf/boards/pca10100/mpconfigboard.mk1
-rw-r--r--ports/nrf/boards/simmel/mpconfigboard.mk5
-rw-r--r--ports/nrf/mpconfigport.h3
-rw-r--r--ports/raspberrypi/.gitignore1
-rw-r--r--ports/raspberrypi/Makefile274
-rw-r--r--ports/raspberrypi/README.rst18
-rw-r--r--ports/raspberrypi/background.c44
-rw-r--r--ports/raspberrypi/background.h32
-rw-r--r--ports/raspberrypi/bindings/rp2pio/StateMachine.c449
-rw-r--r--ports/raspberrypi/bindings/rp2pio/StateMachine.h71
-rw-r--r--ports/raspberrypi/bindings/rp2pio/__init__.c45
-rw-r--r--ports/raspberrypi/boards/adafruit_feather_rp2040/board.c44
-rw-r--r--ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h14
-rw-r--r--ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.mk9
-rw-r--r--ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c36
-rw-r--r--ports/raspberrypi/boards/raspberry_pi_pico/board.c38
-rw-r--r--ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h15
-rw-r--r--ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk9
-rw-r--r--ports/raspberrypi/boards/raspberry_pi_pico/pins.c39
-rw-r--r--ports/raspberrypi/bs2_default_padded_checksummed.S20
-rw-r--r--ports/raspberrypi/common-hal/analogio/AnalogIn.c73
-rw-r--r--ports/raspberrypi/common-hal/analogio/AnalogIn.h41
-rw-r--r--ports/raspberrypi/common-hal/analogio/AnalogOut.c48
-rw-r--r--ports/raspberrypi/common-hal/analogio/AnalogOut.h36
-rw-r--r--ports/raspberrypi/common-hal/analogio/__init__.c1
-rw-r--r--ports/raspberrypi/common-hal/board/__init__.c34
-rw-r--r--ports/raspberrypi/common-hal/busio/I2C.c175
-rw-r--r--ports/raspberrypi/common-hal/busio/I2C.h47
-rw-r--r--ports/raspberrypi/common-hal/busio/OneWire.h33
-rw-r--r--ports/raspberrypi/common-hal/busio/SPI.c294
-rw-r--r--ports/raspberrypi/common-hal/busio/SPI.h52
-rw-r--r--ports/raspberrypi/common-hal/busio/UART.c404
-rw-r--r--ports/raspberrypi/common-hal/busio/UART.h47
-rw-r--r--ports/raspberrypi/common-hal/busio/__init__.c1
-rw-r--r--ports/raspberrypi/common-hal/digitalio/DigitalInOut.c154
-rw-r--r--ports/raspberrypi/common-hal/digitalio/DigitalInOut.h40
-rw-r--r--ports/raspberrypi/common-hal/digitalio/__init__.c1
-rw-r--r--ports/raspberrypi/common-hal/displayio/ParallelBus.c68
-rw-r--r--ports/raspberrypi/common-hal/displayio/ParallelBus.h36
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/Pin.c181
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/Pin.h53
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/Processor.c66
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/Processor.h39
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/__init__.c148
-rw-r--r--ports/raspberrypi/common-hal/microcontroller/__init__.h36
-rw-r--r--ports/raspberrypi/common-hal/neopixel_write/__init__.c95
-rw-r--r--ports/raspberrypi/common-hal/os/__init__.c62
-rw-r--r--ports/raspberrypi/common-hal/pwmio/PWMOut.c216
-rw-r--r--ports/raspberrypi/common-hal/pwmio/PWMOut.h47
-rw-r--r--ports/raspberrypi/common-hal/pwmio/__init__.c1
-rw-r--r--ports/raspberrypi/common-hal/rp2pio/StateMachine.c585
-rw-r--r--ports/raspberrypi/common-hal/rp2pio/StateMachine.h68
-rw-r--r--ports/raspberrypi/common-hal/rp2pio/__init__.c1
-rwxr-xr-xports/raspberrypi/common-hal/supervisor/Runtime.c37
-rwxr-xr-xports/raspberrypi/common-hal/supervisor/Runtime.h37
-rwxr-xr-xports/raspberrypi/common-hal/supervisor/__init__.c40
-rw-r--r--ports/raspberrypi/fatfs_port.c48
-rw-r--r--ports/raspberrypi/link.ld250
-rw-r--r--ports/raspberrypi/mpconfigport.h44
-rw-r--r--ports/raspberrypi/mpconfigport.mk47
-rw-r--r--ports/raspberrypi/mphalport.c57
-rw-r--r--ports/raspberrypi/mphalport.h50
-rw-r--r--ports/raspberrypi/peripherals/pins.c67
-rw-r--r--ports/raspberrypi/peripherals/pins.h71
-rw-r--r--ports/raspberrypi/qstrdefsport.h1
m---------ports/raspberrypi/sdk0
-rw-r--r--ports/raspberrypi/sdk_config/pico/config_autogen.h19
-rw-r--r--ports/raspberrypi/sdk_config/pico/version.h19
-rw-r--r--ports/raspberrypi/supervisor/internal_flash.c131
-rw-r--r--ports/raspberrypi/supervisor/internal_flash.h38
-rw-r--r--ports/raspberrypi/supervisor/internal_flash_root_pointers.h31
-rw-r--r--ports/raspberrypi/supervisor/port.c200
-rwxr-xr-xports/raspberrypi/supervisor/rp2_cpu.s35
-rw-r--r--ports/raspberrypi/supervisor/usb.c53
-rw-r--r--ports/stm/boards/espruino_pico/mpconfigboard.mk1
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c39
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.h52
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk19
-rw-r--r--ports/stm/boards/stm32f411ce_blackpill_with_flash/pins.c44
-rw-r--r--ports/stm/mpconfigport.h2
-rw-r--r--py/builtinhelp.c13
-rw-r--r--py/circuitpy_defns.mk4
-rw-r--r--py/circuitpy_mpconfig.h105
-rw-r--r--py/circuitpy_mpconfig.mk22
-rw-r--r--shared-bindings/_eve/__init__.c150
-rw-r--r--shared-bindings/_eve/__init__.h8
-rw-r--r--shared-bindings/adafruit_bus_device/I2CDevice.c81
-rw-r--r--shared-bindings/adafruit_bus_device/I2CDevice.h4
-rw-r--r--shared-bindings/microcontroller/Pin.c8
-rw-r--r--shared-bindings/microcontroller/__init__.h7
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.c28
-rw-r--r--shared-bindings/rgbmatrix/RGBMatrix.h2
-rw-r--r--shared-bindings/socketpool/Socket.c156
-rw-r--r--shared-bindings/socketpool/Socket.h5
-rw-r--r--shared-bindings/socketpool/SocketPool.c6
-rw-r--r--shared-bindings/support_matrix.rst4
-rw-r--r--shared-module/_eve/__init__.c20
-rw-r--r--shared-module/adafruit_bus_device/I2CDevice.c50
-rw-r--r--shared-module/adafruit_bus_device/I2CDevice.h2
-rw-r--r--shared-module/msgpack/__init__.c21
-rw-r--r--shared-module/os/__init__.c2
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.c11
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.h2
-rw-r--r--shared-module/sdcardio/SDCard.c4
-rw-r--r--supervisor/shared/filesystem.c2
-rw-r--r--supervisor/shared/safe_mode.c2
-rw-r--r--supervisor/shared/usb/usb.c4
-rw-r--r--supervisor/usb.h3
-rw-r--r--tools/build_board_info.py2
-rw-r--r--tools/build_memory_info.py4
189 files changed, 7661 insertions, 1136 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0b2a9058f..0dbccdf4d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -177,6 +177,7 @@ jobs:
- "8086_commander"
- "ADM_B_NRF52840_1"
- "TG-Watch"
+ - "adafruit_feather_rp2040"
- "aloriumtech_evo_m51"
- "aramcon_badge_2019"
- "arduino_mkr1300"
@@ -294,6 +295,7 @@ jobs:
- "pyruler"
- "qtpy_m0"
- "qtpy_m0_haxpress"
+ - "raspberry_pi_pico"
- "raytac_mdbt50q-db-40"
- "robohatmm1_m4"
- "sam32"
@@ -315,6 +317,7 @@ jobs:
- "spresense"
- "stackrduino_m0_pro"
- "stm32f411ce_blackpill"
+ - "stm32f411ce_blackpill_with_flash"
- "stm32f411ve_discovery"
- "stm32f412zg_discovery"
- "stm32f4_discovery"
@@ -464,7 +467,7 @@ jobs:
id: idf-cache
with:
path: ${{ github.workspace }}/.idf_tools
- key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20210114
+ key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/esp32s2/esp-idf/HEAD') }}-20210122
- name: Clone IDF submodules
run: |
(cd $IDF_PATH && git submodule update --init)
diff --git a/.gitmodules b/.gitmodules
index f4080de1b..99de2c918 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -171,3 +171,6 @@
[submodule "frozen/Adafruit_CircuitPython_LC709203F"]
path = frozen/Adafruit_CircuitPython_LC709203F
url = https://github.com/adafruit/Adafruit_CircuitPython_LC709203F
+[submodule "ports/raspberrypi/sdk"]
+ path = ports/raspberrypi/sdk
+ url = https://github.com/raspberrypi/pico-sdk.git
diff --git a/Makefile b/Makefile
index adb206d7b..845997beb 100644
--- a/Makefile
+++ b/Makefile
@@ -255,6 +255,7 @@ stubs:
@$(PYTHON) tools/extract_pyi.py shared-bindings/ $(STUBDIR)
@$(PYTHON) tools/extract_pyi.py extmod/ulab/code/ $(STUBDIR)/ulab
@$(PYTHON) tools/extract_pyi.py ports/atmel-samd/bindings $(STUBDIR)
+ @$(PYTHON) tools/extract_pyi.py ports/raspberrypi/bindings $(STUBDIR)
@$(PYTHON) setup.py -q sdist
.PHONY: check-stubs
diff --git a/README.rst b/README.rst
index 19992d284..f14cf41ff 100644
--- a/README.rst
+++ b/README.rst
@@ -125,7 +125,7 @@ Behavior
get back into normal mode.
- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
- ``samd.disable_autoreload()``)
+ ``supervisor.disable_autoreload()``)
- Entering the REPL after the main code is finished requires a key press which enters the REPL and
disables autoreload.
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
diff --git a/conf.py b/conf.py
index c2d3d37ee..0a163e7d3 100644
--- a/conf.py
+++ b/conf.py
@@ -189,6 +189,7 @@ exclude_patterns = ["**/build*",
"ports/nrf/nrfx",
"ports/nrf/peripherals",
"ports/nrf/usb",
+ "ports/raspberrypi/sdk",
"ports/stm/st_driver",
"ports/stm/packages",
"ports/stm/peripherals",
diff --git a/docs/design_guide.rst b/docs/design_guide.rst
index 75825893a..7a8c76b50 100644
--- a/docs/design_guide.rst
+++ b/docs/design_guide.rst
@@ -520,7 +520,9 @@ properties.
+-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``temperature`` | float | degrees centigrade |
+-----------------------+-----------------------+-------------------------------------------------------------------------+
-| ``eCO2`` | float | equivalent CO2 in ppm |
+| ``CO2`` | float | measured CO2 in ppm |
++-----------------------+-----------------------+-------------------------------------------------------------------------+
+| ``eCO2`` | float | equivalent/estimated CO2 in ppm (estimated from some other measurement) |
+-----------------------+-----------------------+-------------------------------------------------------------------------+
| ``TVOC`` | float | Total Volatile Organic Compounds in ppb |
+-----------------------+-----------------------+-------------------------------------------------------------------------+
diff --git a/docs/library/uerrno.rst b/docs/library/errno.rst
index 72f71f0aa..96777b205 100644
--- a/docs/library/uerrno.rst
+++ b/docs/library/errno.rst
@@ -1,9 +1,7 @@
-:mod:`uerrno` -- system error codes
+:mod:`errno` -- system error codes
===================================
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: uerrno
+.. module:: errno
:synopsis: system error codes
|see_cpython_module| :mod:`cpython:errno`.
@@ -22,7 +20,7 @@ Constants
try:
os.mkdir("my_dir")
except OSError as exc:
- if exc.args[0] == uerrno.EEXIST:
+ if exc.args[0] == errno.EEXIST:
print("Directory already exists")
.. data:: errorcode
@@ -30,5 +28,5 @@ Constants
Dictionary mapping numeric error codes to strings with symbolic error
code (see above)::
- >>> print(uerrno.errorcode[uerrno.EEXIST])
+ >>> print(errno.errorcode[uerrno.EEXIST])
EEXIST
diff --git a/docs/library/esp.rst b/docs/library/esp.rst
deleted file mode 100644
index 125aaa890..000000000
--- a/docs/library/esp.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-:mod:`esp` --- functions related to the ESP8266
-===============================================
-
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: esp
- :synopsis: functions related to the ESP8266
-
-The ``esp`` module contains specific functions related to the ESP8266 module.
-
-
-Functions
----------
-
-.. function:: sleep_type([sleep_type])
-
- Get or set the sleep type.
-
- If the *sleep_type* parameter is provided, sets the sleep type to its
- value. If the function is called without parameters, returns the current
- sleep type.
-
- The possible sleep types are defined as constants:
-
- * ``SLEEP_NONE`` -- all functions enabled,
- * ``SLEEP_MODEM`` -- modem sleep, shuts down the WiFi Modem circuit.
- * ``SLEEP_LIGHT`` -- light sleep, shuts down the WiFi Modem circuit
- and suspends the processor periodically.
-
- The system enters the set sleep mode automatically when possible.
-
-.. function:: deepsleep(time=0)
-
- Enter deep sleep.
-
- The whole module powers down, except for the RTC clock circuit, which can
- be used to restart the module after the specified time if the pin 16 is
- connected to the reset pin. Otherwise the module will sleep until manually
- reset.
-
-.. function:: flash_id()
-
- Read the device ID of the flash memory.
-
-.. function:: flash_read(byte_offset, length_or_buffer)
-
-.. function:: flash_write(byte_offset, bytes)
-
-.. function:: flash_erase(sector_no)
-
-.. function:: set_native_code_location(start, length)
-
- Set the location that native code will be placed for execution after it is
- compiled. Native code is emitted when the ``@micropython.native``,
- ``@micropython.viper`` and ``@micropython.asm_xtensa`` decorators are applied
- to a function. The ESP8266 must execute code from either iRAM or the lower
- 1MByte of flash (which is memory mapped), and this function controls the
- location.
-
- If *start* and *length* are both ``None`` then the native code location is
- set to the unused portion of memory at the end of the iRAM1 region. The
- size of this unused portion depends on the firmware and is typically quite
- small (around 500 bytes), and is enough to store a few very small
- functions. The advantage of using this iRAM1 region is that it does not
- get worn out by writing to it.
-
- If neither *start* nor *length* are ``None`` then they should be integers.
- *start* should specify the byte offset from the beginning of the flash at
- which native code should be stored. *length* specifies how many bytes of
- flash from *start* can be used to store native code. *start* and *length*
- should be multiples of the sector size (being 4096 bytes). The flash will
- be automatically erased before writing to it so be sure to use a region of
- flash that is not otherwise used, for example by the firmware or the
- filesystem.
-
- When using the flash to store native code *start+length* must be less
- than or equal to 1MByte. Note that the flash can be worn out if repeated
- erasures (and writes) are made so use this feature sparingly.
- In particular, native code needs to be recompiled and rewritten to flash
- on each boot (including wake from deepsleep).
-
- In both cases above, using iRAM1 or flash, if there is no more room left
- in the specified region then the use of a native decorator on a function
- will lead to `MemoryError` exception being raised during compilation of
- that function.
diff --git a/docs/library/index.rst b/docs/library/index.rst
index e91387242..181ff0109 100644
--- a/docs/library/index.rst
+++ b/docs/library/index.rst
@@ -6,35 +6,21 @@ MicroPython libraries
Python standard libraries and micro-libraries
---------------------------------------------
-These libraries are inherited from MicroPython.
-They are similar to the standard Python libraries with the same name
-or with the "u" prefix dropped.
+The libraries below are inherited from MicroPython.
+They are similar to the standard Python libraries with the same name.
They implement a subset of or a variant of the corresponding
standard Python library.
-.. warning::
-
- Though these MicroPython-based libraries are available in CircuitPython,
- their functionality may change in the future, perhaps significantly.
- As CircuitPython continues to develop, new versions of these libraries will
- be created that are more compliant with the standard Python libraries.
- You may need to change your code later if you rely
- on any non-standard functionality they currently provide.
-
CircuitPython's long-term goal is that code written in CircuitPython
using Python standard libraries will be runnable on CPython without changes.
-Some libraries below are not enabled on CircuitPython builds with
+These libraries are not enabled on CircuitPython builds with
limited flash memory, usually on non-Express builds:
-``uerrno``, ``ure``.
-
-Some libraries are not currently enabled in any CircuitPython build, but may be in the future:
-``uio``, ``ujson``, ``uzlib``.
+``binascii``, ``errno``, ``json``, ``re``.
-Some libraries are only enabled only WiFi-capable ports (ESP8266, nRF)
-because they are typically used for network software:
-``binascii``, ``hashlib``, ``uheapq``, ``uselect``, ``ussl``.
-Not all of these are enabled on all WiFi-capable ports.
+These libraries are not currently enabled in any CircuitPython build, but may be in the future,
+with the ``u`` prefix dropped:
+``uctypes``, ``uhashlib``, ``uzlib``.
.. toctree::
:maxdepth: 1
@@ -44,13 +30,14 @@ Not all of these are enabled on all WiFi-capable ports.
array.rst
binascii.rst
collections.rst
+ errno.rst
gc.rst
hashlib.rst
+ io.rst
+ json.rst
+ re.rst
sys.rst
- uerrno.rst
- uio.rst
- ujson.rst
- ure.rst
+ uctypes.rst
uselect.rst
usocket.rst
ussl.rst
@@ -59,8 +46,8 @@ Not all of these are enabled on all WiFi-capable ports.
Omitted functions in the ``string`` library
-------------------------------------------
-A few string operations are not enabled on CircuitPython
-M0 non-Express builds, due to limited flash memory:
+A few string operations are not enabled on small builds
+(usually non-Express), due to limited flash memory:
``string.center()``, ``string.partition()``, ``string.splitlines()``,
``string.reversed()``.
@@ -78,15 +65,3 @@ versions of CircuitPython.
btree.rst
framebuf.rst
micropython.rst
- network.rst
- uctypes.rst
-
-Libraries specific to the ESP8266
----------------------------------
-
-The following libraries are specific to the ESP8266.
-
-.. toctree::
- :maxdepth: 2
-
- esp.rst
diff --git a/docs/library/uio.rst b/docs/library/io.rst
index d1f7c111f..37e3eb7c9 100644
--- a/docs/library/uio.rst
+++ b/docs/library/io.rst
@@ -1,9 +1,7 @@
-:mod:`uio` -- input/output streams
+:mod:`io` -- input/output streams
==================================
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: uio
+.. module:: io
:synopsis: input/output streams
|see_cpython_module| :mod:`cpython:io`.
diff --git a/docs/library/ujson.rst b/docs/library/json.rst
index 4ed91f053..21574e556 100644
--- a/docs/library/ujson.rst
+++ b/docs/library/json.rst
@@ -1,9 +1,7 @@
-:mod:`ujson` -- JSON encoding and decoding
+:mod:`json` -- JSON encoding and decoding
==========================================
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: ujson
+.. module:: json
:synopsis: JSON encoding and decoding
|see_cpython_module| :mod:`cpython:json`.
diff --git a/docs/library/network.rst b/docs/library/network.rst
deleted file mode 100644
index 3bd41150d..000000000
--- a/docs/library/network.rst
+++ /dev/null
@@ -1,278 +0,0 @@
-****************************************
-:mod:`network` --- network configuration
-****************************************
-
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: network
- :noindex:
- :synopsis: network configuration
-
-This module provides network drivers and routing configuration. To use this
-module, a MicroPython variant/build with network capabilities must be installed.
-Network drivers for specific hardware are available within this module and are
-used to configure hardware network interface(s). Network services provided
-by configured interfaces are then available for use via the :mod:`usocket`
-module.
-
-For example::
-
- # connect/ show IP config a specific network interface
- # see below for examples of specific drivers
- import network
- import utime
- nic = network.Driver(...)
- if not nic.isconnected():
- nic.connect()
- print("Waiting for connection...")
- while not nic.isconnected():
- utime.sleep(1)
- print(nic.ifconfig())
-
- # now use usocket as usual
- import usocket as socket
- addr = socket.getaddrinfo('micropython.org', 80)[0][-1]
- s = socket.socket()
- s.connect(addr)
- s.send(b'GET / HTTP/1.1\r\nHost: micropython.org\r\n\r\n')
- data = s.recv(1000)
- s.close()
-
-Common network adapter interface
-================================
-
-This section describes an (implied) abstract base class for all network
-interface classes implemented by ``MicroPython ports <MicroPython port>``
-for different hardware. This means that MicroPython does not actually
-provide ``AbstractNIC`` class, but any actual NIC class, as described
-in the following sections, implements methods as described here.
-
-.. class:: AbstractNIC(id=None, ...)
-
-Instantiate a network interface object. Parameters are network interface
-dependent. If there are more than one interface of the same type, the first
-parameter should be `id`.
-
- .. method:: active([is_active])
-
- Activate ("up") or deactivate ("down") the network interface, if
- a boolean argument is passed. Otherwise, query current state if
- no argument is provided. Most other methods require an active
- interface (behavior of calling them on inactive interface is
- undefined).
-
- .. method:: connect([service_id, key=None, \*, ...])
-
- Connect the interface to a network. This method is optional, and
- available only for interfaces which are not "always connected".
- If no parameters are given, connect to the default (or the only)
- service. If a single parameter is given, it is the primary identifier
- of a service to connect to. It may be accompanied by a key
- (password) required to access said service. There can be further
- arbitrary keyword-only parameters, depending on the networking medium
- type and/or particular device. Parameters can be used to: a)
- specify alternative service identifier types; b) provide additional
- connection parameters. For various medium types, there are different
- sets of predefined/recommended parameters, among them:
-
- * WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
-
- .. method:: disconnect()
-
- Disconnect from network.
-
- .. method:: isconnected()
-
- Returns ``True`` if connected to network, otherwise returns ``False``.
-
- .. method:: scan(\*, ...)
-
- Scan for the available network services/connections. Returns a
- list of tuples with discovered service parameters. For various
- network media, there are different variants of predefined/
- recommended tuple formats, among them:
-
- * WiFi: (ssid, bssid, channel, RSSI, authmode, hidden). There
- may be further fields, specific to a particular device.
-
- The function may accept additional keyword arguments to filter scan
- results (e.g. scan for a particular service, on a particular channel,
- for services of a particular set, etc.), and to affect scan
- duration and other parameters. Where possible, parameter names
- should match those in connect().
-
- .. method:: status()
-
- Return detailed status of the interface, values are dependent
- on the network medium/technology.
-
- .. method:: ifconfig([(ip, subnet, gateway, dns)])
-
- Get/set IP-level network interface parameters: IP address, subnet mask,
- gateway and DNS server. When called with no arguments, this method returns
- a 4-tuple with the above information. To set the above values, pass a
- 4-tuple with the required information. For example::
-
- nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
-
- .. method:: config('param')
- config(param=value, ...)
-
- Get or set general network interface parameters. These methods allow to work
- with additional parameters beyond standard IP configuration (as dealt with by
- `ifconfig()`). These include network-specific and hardware-specific
- parameters and status values. For setting parameters, the keyword argument
- syntax should be used, and multiple parameters can be set at once. For
- querying, a parameter name should be quoted as a string, and only one
- parameter can be queried at a time::
-
- # Set WiFi access point name (formally known as ESSID) and WiFi channel
- ap.config(essid='My AP', channel=11)
- # Query params one by one
- print(ap.config('essid'))
- print(ap.config('channel'))
- # Extended status information also available this way
- print(sta.config('rssi'))
-
-.. _network.WLAN:
-
-Functions
-=========
-
-.. function:: phy_mode([mode])
-
- Get or set the PHY mode.
-
- If the *mode* parameter is provided, sets the mode to its value. If
- the function is called without parameters, returns the current mode.
-
- The possible modes are defined as constants:
- * ``MODE_11B`` -- IEEE 802.11b,
- * ``MODE_11G`` -- IEEE 802.11g,
- * ``MODE_11N`` -- IEEE 802.11n.
-
-class WLAN
-==========
-
-This class provides a driver for WiFi network processor in the ESP8266. Example usage::
-
- import network
- # enable station interface and connect to WiFi access point
- nic = network.WLAN(network.STA_IF)
- nic.active(True)
- nic.connect('your-ssid', 'your-password')
- # now use sockets as usual
-
-Constructors
-------------
-.. class:: WLAN(interface_id)
-
-Create a WLAN network interface object. Supported interfaces are
-``network.STA_IF`` (station aka client, connects to upstream WiFi access
-points) and ``network.AP_IF`` (access point, allows other WiFi clients to
-connect). Availability of the methods below depends on interface type.
-For example, only STA interface may `connect()` to an access point.
-
-Methods
--------
-
-.. method:: wlan.active([is_active])
-
- Activate ("up") or deactivate ("down") network interface, if boolean
- argument is passed. Otherwise, query current state if no argument is
- provided. Most other methods require active interface.
-
-.. method:: wlan.connect(ssid=None, password=None, \*, bssid=None)
-
- Connect to the specified wireless network, using the specified password.
- If *bssid* is given then the connection will be restricted to the
- access-point with that MAC address (the *ssid* must also be specified
- in this case).
-
-.. method:: wlan.disconnect()
-
- Disconnect from the currently connected wireless network.
-
-.. method:: wlan.scan()
-
- Scan for the available wireless networks.
-
- Scanning is only possible on STA interface. Returns list of tuples with
- the information about WiFi access points:
-
- (ssid, bssid, channel, RSSI, authmode, hidden)
-
- *bssid* is hardware address of an access point, in binary form, returned as
- bytes object. You can use `binascii.hexlify()` to convert it to ASCII form.
-
- There are five values for authmode:
-
- * 0 -- open
- * 1 -- WEP
- * 2 -- WPA-PSK
- * 3 -- WPA2-PSK
- * 4 -- WPA/WPA2-PSK
-
- and two for hidden:
-
- * 0 -- visible
- * 1 -- hidden
-
-.. method:: wlan.status()
-
- Return the current status of the wireless connection.
-
- The possible statuses are defined as constants:
-
- * ``STAT_IDLE`` -- no connection and no activity,
- * ``STAT_CONNECTING`` -- connecting in progress,
- * ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password,
- * ``STAT_NO_AP_FOUND`` -- failed because no access point replied,
- * ``STAT_CONNECT_FAIL`` -- failed due to other problems,
- * ``STAT_GOT_IP`` -- connection successful.
-
-.. method:: wlan.isconnected()
-
- In case of STA mode, returns ``True`` if connected to a WiFi access
- point and has a valid IP address. In AP mode returns ``True`` when a
- station is connected. Returns ``False`` otherwise.
-
-.. method:: wlan.ifconfig([(ip, subnet, gateway, dns)])
-
- Get/set IP-level network interface parameters: IP address, subnet mask,
- gateway and DNS server. When called with no arguments, this method returns
- a 4-tuple with the above information. To set the above values, pass a
- 4-tuple with the required information. For example::
-
- nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
-
-.. method:: wlan.config('param')
- wlan.config(param=value, ...)
-
- Get or set general network interface parameters. These methods allow to work
- with additional parameters beyond standard IP configuration (as dealt with by
- `wlan.ifconfig()`). These include network-specific and hardware-specific
- parameters. For setting parameters, keyword argument syntax should be used,
- multiple parameters can be set at once. For querying, parameters name should
- be quoted as a string, and only one parameter can be queries at time::
-
- # Set WiFi access point name (formally known as ESSID) and WiFi channel
- ap.config(essid='My AP', channel=11)
- # Query params one by one
- print(ap.config('essid'))
- print(ap.config('channel'))
-
- Following are commonly supported parameters (availability of a specific parameter
- depends on network technology type, driver, and ``MicroPython port``).
-
- ============= ===========
- Parameter Description
- ============= ===========
- mac MAC address (bytes)
- essid WiFi access point name (string)
- channel WiFi channel (integer)
- hidden Whether ESSID is hidden (boolean)
- authmode Authentication mode supported (enumeration, see module constants)
- password Access password (string)
- dhcp_hostname The DHCP hostname to use
- ============= ===========
diff --git a/docs/library/ure.rst b/docs/library/re.rst
index 4af182b01..bdcc9f52c 100644
--- a/docs/library/ure.rst
+++ b/docs/library/re.rst
@@ -1,9 +1,7 @@
-:mod:`ure` -- simple regular expressions
+:mod:`re` -- simple regular expressions
========================================
-.. include:: ../templates/unsupported_in_circuitpython.inc
-
-.. module:: ure
+.. module:: re
:synopsis: regular expressions
|see_cpython_module| :mod:`cpython:re`.
@@ -77,7 +75,7 @@ Regex objects
-------------
Compiled regular expression. Instances of this class are created using
-`ure.compile()`.
+`re.compile()`.
.. method:: regex.match(string)
regex.search(string)
diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py
index f38c0b64a..e62b1d218 100644
--- a/docs/shared_bindings_matrix.py
+++ b/docs/shared_bindings_matrix.py
@@ -30,7 +30,7 @@ import sys
from concurrent.futures import ThreadPoolExecutor
-SUPPORTED_PORTS = ['atmel-samd', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'stm']
+SUPPORTED_PORTS = ['atmel-samd', 'cxd56', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm']
def get_circuitpython_root_dir():
""" The path to the root './circuitpython' directory
@@ -44,7 +44,7 @@ def get_shared_bindings():
""" Get a list of modules in shared-bindings based on folder names
"""
shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings"
- return [item.name for item in shared_bindings_dir.iterdir()] + ["ulab"]
+ return [item.name for item in shared_bindings_dir.iterdir()] + ["binascii", "errno", "json", "re", "ulab"]
def read_mpconfig():
diff --git a/docs/supported_ports.rst b/docs/supported_ports.rst
index e74067e28..b83ef12d3 100644
--- a/docs/supported_ports.rst
+++ b/docs/supported_ports.rst
@@ -13,8 +13,9 @@ is limited.
../ports/atmel-samd/README
../ports/cxd56/README
+ ../ports/esp32s2/README
../ports/litex/README
../ports/mimxrt10xx/README
../ports/nrf/README
+ ../ports/raspberrypi/README
../ports/stm/README
- ../ports/esp32s2/README
diff --git a/extmod/vfs.c b/extmod/vfs.c
index c9c1fe3c3..420f8305f 100644
--- a/extmod/vfs.c
+++ b/extmod/vfs.c
@@ -71,6 +71,7 @@ mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) {
STATIC mp_vfs_mount_t *lookup_path(mp_obj_t path_in, mp_obj_t *path_out) {
const char *path = mp_obj_str_get_str(path_in);
const char *p_out;
+ *path_out = mp_const_none;
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out);
if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) {
*path_out = mp_obj_new_str_of_type(mp_obj_get_type(path_in),
@@ -329,7 +330,7 @@ mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args) {
path_in = MP_OBJ_NEW_QSTR(MP_QSTR_);
}
- mp_obj_t path_out;
+ mp_obj_t path_out = mp_const_none;
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
if (vfs == MP_VFS_ROOT) {
@@ -359,7 +360,7 @@ mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args) {
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_listdir_obj, 0, 1, mp_vfs_listdir);
mp_obj_t mp_vfs_mkdir(mp_obj_t path_in) {
- mp_obj_t path_out;
+ mp_obj_t path_out = mp_const_none;
mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out);
if (vfs == MP_VFS_ROOT || (vfs != MP_VFS_NONE && !strcmp(mp_obj_str_get_str(path_out), "/"))) {
mp_raise_OSError(MP_EEXIST);
diff --git a/lib/protomatter b/lib/protomatter
-Subproject 902c16f49197a8baf5e71ec924a812a86e733a7
+Subproject 5e925cea7a55273e375a6129761cb29b4e750d4
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject cfcffe94ce62f5ef1fb5aef4641924d64dc4b1c
+Subproject 045674745afa59028fbeed6dac5cb5a9c4a6033
diff --git a/locale/ID.po b/locale/ID.po
index 6aa4f0fba..7ae5b50bd 100644
--- a/locale/ID.po
+++ b/locale/ID.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-01-03 05:29+0000\n"
+"PO-Revision-Date: 2021-01-15 19:49+0000\n"
"Last-Translator: oon arfiandwi <oon.arfiandwi@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: ID\n"
@@ -14,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4.1-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
@@ -48,6 +48,10 @@ msgstr " File \"%q\""
msgid " File \"%q\", line %d"
msgstr " File \"%q\", baris %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr "output:\n"
@@ -869,6 +873,10 @@ msgstr "Channel EXTINT sedang digunakan"
msgid "Error in regex"
msgstr "Error pada regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1261,10 +1269,18 @@ msgstr "security_mode tidak valid"
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "Suara tidak valid"
@@ -1281,6 +1297,10 @@ msgstr "File wave tidak valid"
msgid "Invalid word/bit length"
msgstr "Panjang kata/bit tidak valid"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Panjang kunci harus 16, 24, atau 32 byte"
@@ -1569,7 +1589,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2054,38 +2074,41 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown gatt error: 0x%04x"
-msgstr ""
+msgstr "Kesalahan gatt tidak dikenal: 0x%04x"
#: supervisor/shared/safe_mode.c
msgid "Unknown reason."
-msgstr ""
+msgstr "Alasan yang tidak diketahui."
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown security error: 0x%04x"
-msgstr ""
+msgstr "Kesalahan keamanan tidak dikenal: 0x%04x"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown soft device error: %04x"
-msgstr ""
+msgstr "Kesalahan perangkat lunak tidak dikenal: %04x"
#: shared-bindings/_pixelbuf/PixelBuf.c
#, c-format
msgid "Unmatched number of items on RHS (expected %d, got %d)."
-msgstr ""
+msgstr "Jumlah item pada RHS tidak cocok (diharapkan %d, didapatkan %d)."
#: ports/nrf/common-hal/_bleio/__init__.c
msgid ""
"Unspecified issue. Can be that the pairing prompt on the other device was "
"declined or ignored."
msgstr ""
+"Masalah yang tidak ditentukan. Bisa jadi permintaan pemasangan pada "
+"perangkat lain ditolak atau diabaikan."
#: ports/atmel-samd/common-hal/busio/I2C.c ports/cxd56/common-hal/busio/I2C.c
#: ports/esp32s2/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c
@@ -2099,15 +2122,15 @@ msgstr "Baudrate tidak didukung"
#: shared-module/audiocore/WaveFile.c
msgid "Unsupported format"
-msgstr ""
+msgstr "Format tidak didukung"
#: py/moduerrno.c
msgid "Unsupported operation"
-msgstr ""
+msgstr "Operasi yang tidak didukung"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Unsupported pull value."
-msgstr ""
+msgstr "Nilai tarikan yang tidak didukung."
#: ports/esp32s2/common-hal/dualbank/__init__.c
msgid "Update Failed"
@@ -2116,12 +2139,12 @@ msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#: ports/nrf/common-hal/_bleio/Descriptor.c
msgid "Value length != required fixed length"
-msgstr ""
+msgstr "Panjang nilai != Panjang tetap yang dibutuhkan"
#: ports/nrf/common-hal/_bleio/Characteristic.c
#: ports/nrf/common-hal/_bleio/Descriptor.c
msgid "Value length > max_length"
-msgstr ""
+msgstr "Panjang nilai > max_length"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Version was invalid"
@@ -2129,11 +2152,11 @@ msgstr ""
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
-msgstr ""
+msgstr "Fungsi Viper saat ini tidak mendukung lebih dari 4 argumen"
#: ports/stm/common-hal/microcontroller/Processor.c
msgid "Voltage read timed out"
-msgstr ""
+msgstr "Tegangan baca habis waktu"
#: main.c
msgid "WARNING: Your code filename has two extensions\n"
@@ -2185,11 +2208,11 @@ msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Writes not supported on Characteristic"
-msgstr ""
+msgstr "Menulis tidak didukung pada Karakteristik"
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
-msgstr ""
+msgstr "Anda berada dalam mode aman: sesuatu yang tidak terduga terjadi.\n"
#: supervisor/shared/safe_mode.c
msgid "You requested starting safe mode by "
@@ -2197,7 +2220,7 @@ msgstr "Anda mengajukan untuk memulai mode aman pada (safe mode) pada "
#: py/objtype.c
msgid "__init__() should return None"
-msgstr ""
+msgstr "__init __() harus mengembalikan None"
#: py/objtype.c
msgid "__init__() should return None, not '%q'"
@@ -2205,7 +2228,7 @@ msgstr ""
#: py/objobject.c
msgid "__new__ arg must be a user-type"
-msgstr ""
+msgstr "__new__ arg harus berupa user-type"
#: extmod/modubinascii.c extmod/moduhashlib.c py/objarray.c
msgid "a bytes-like object is required"
@@ -2222,19 +2245,19 @@ msgstr "alamat %08x tidak selaras dengan %d bytes"
#: shared-bindings/i2cperipheral/I2CPeripheral.c
msgid "address out of bounds"
-msgstr ""
+msgstr "alamat di luar batas"
#: shared-bindings/i2cperipheral/I2CPeripheral.c
msgid "addresses is empty"
-msgstr ""
+msgstr "alamatnya kosong"
#: py/modbuiltins.c
msgid "arg is an empty sequence"
-msgstr ""
+msgstr "arg berisi urutan kosong"
#: extmod/ulab/code/numerical/numerical.c
msgid "argsort argument must be an ndarray"
-msgstr ""
+msgstr "Argumen argsort harus berupa ndarray"
#: extmod/ulab/code/numerical/numerical.c
msgid "argsort is not implemented for flattened arrays"
@@ -2242,7 +2265,7 @@ msgstr ""
#: py/runtime.c
msgid "argument has wrong type"
-msgstr ""
+msgstr "argumen memiliki tipe yang salah"
#: extmod/ulab/code/linalg/linalg.c
msgid "argument must be ndarray"
@@ -2255,11 +2278,11 @@ msgstr "argumen num/types tidak cocok"
#: py/runtime.c
msgid "argument should be a '%q' not a '%q'"
-msgstr ""
+msgstr "argumen harus berupa '%q' bukan '%q'"
#: extmod/ulab/code/linalg/linalg.c extmod/ulab/code/numerical/numerical.c
msgid "arguments must be ndarrays"
-msgstr ""
+msgstr "argumen harus berupa ndarrays"
#: extmod/ulab/code/ndarray.c
msgid "array and index length must be equal"
@@ -2268,7 +2291,7 @@ msgstr ""
#: py/objarray.c shared-bindings/alarm/SleepMemory.c
#: shared-bindings/nvm/ByteArray.c
msgid "array/bytes required on right side"
-msgstr ""
+msgstr "diperlukan array/byte di sisi kanan"
#: extmod/ulab/code/numerical/numerical.c
msgid "attempt to get (arg)min/(arg)max of empty sequence"
@@ -2276,11 +2299,11 @@ msgstr ""
#: extmod/ulab/code/numerical/numerical.c
msgid "attempt to get argmin/argmax of an empty sequence"
-msgstr ""
+msgstr "berusaha mendapatkan argmin/argmax dari urutan kosong"
#: py/objstr.c
msgid "attributes not supported yet"
-msgstr ""
+msgstr "atribut belum didukung"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis is out of bounds"
@@ -2300,7 +2323,7 @@ msgstr "mode compile buruk"
#: py/objstr.c
msgid "bad conversion specifier"
-msgstr ""
+msgstr "specifier salah konversi"
#: py/objstr.c
msgid "bad format string"
@@ -2326,10 +2349,18 @@ msgstr ""
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
#, fuzzy
msgid "buffer size must match format"
@@ -3332,6 +3363,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3388,6 +3423,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
#, fuzzy
msgid "offset out of bounds"
@@ -3944,6 +3983,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index c321db002..ad605a2db 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -43,6 +43,10 @@ msgstr ""
msgid " File \"%q\", line %d"
msgstr ""
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr ""
@@ -54,7 +58,8 @@ msgstr ""
#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
-msgid "%d address pins and %d rgb pins indicate a height of %d, not %d"
+msgid ""
+"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"
msgstr ""
#: ports/atmel-samd/common-hal/sdioio/SDCard.c
@@ -512,7 +517,6 @@ msgstr ""
msgid "Buffer must be a multiple of 512 bytes"
msgstr ""
-#: shared-bindings/adafruit_bus_device/I2CDevice.c
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
@@ -527,6 +531,7 @@ msgid "Buffer too short by %d bytes"
msgstr ""
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
+#: ports/esp32s2/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
msgid "Bus pin %d is already in use"
@@ -796,6 +801,10 @@ msgstr ""
msgid "Data 0 pin must be byte aligned"
msgstr ""
+#: ports/esp32s2/common-hal/displayio/ParallelBus.c
+msgid "Data 0 pin must be byte aligned."
+msgstr ""
+
#: shared-module/audiocore/WaveFile.c
msgid "Data chunk must follow fmt chunk"
msgstr ""
@@ -850,6 +859,10 @@ msgstr ""
msgid "Error in regex"
msgstr ""
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1240,10 +1253,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1260,6 +1281,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1542,7 +1567,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -1564,7 +1589,6 @@ msgid ""
"PWM frequency not writable when variable_frequency is False on construction."
msgstr ""
-#: ports/esp32s2/common-hal/displayio/ParallelBus.c
#: ports/mimxrt10xx/common-hal/displayio/ParallelBus.c
#: ports/stm/common-hal/displayio/ParallelBus.c
msgid "ParallelBus not yet supported"
@@ -3300,6 +3324,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3694,6 +3722,10 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr ""
+#: shared-bindings/rgbmatrix/RGBMatrix.c
+msgid "tile must be greater than zero"
+msgstr ""
+
#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
@@ -3914,6 +3946,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/cs.po b/locale/cs.po
index a27a1459a..d7ab891b6 100644
--- a/locale/cs.po
+++ b/locale/cs.po
@@ -46,6 +46,10 @@ msgstr " Soubor \"%q\""
msgid " File \"%q\", line %d"
msgstr " Soubor \"%q\", řádek %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " výstup:\n"
@@ -853,6 +857,10 @@ msgstr ""
msgid "Error in regex"
msgstr ""
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1243,10 +1251,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1263,6 +1279,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1545,7 +1565,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2016,7 +2036,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2281,10 +2302,18 @@ msgstr ""
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr ""
@@ -3286,6 +3315,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3342,6 +3375,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr ""
@@ -3896,6 +3933,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 350c7aac1..25321f63e 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -47,6 +47,10 @@ msgstr " Datei \"%q\""
msgid " File \"%q\", line %d"
msgstr " Datei \"%q\", Zeile %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " Ausgabe:\n"
@@ -865,6 +869,10 @@ msgstr "EXTINT Kanal ist schon in Benutzung"
msgid "Error in regex"
msgstr "Fehler in regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1260,10 +1268,18 @@ msgstr "Ungültiger security_mode"
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "Ungültige Stimme"
@@ -1280,6 +1296,10 @@ msgstr "Ungültige wave Datei"
msgid "Invalid word/bit length"
msgstr "Ungültige Wort- / Bitlänge"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Der Schlüssel muss 16, 24 oder 32 Byte lang sein"
@@ -1570,7 +1590,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2058,7 +2078,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2338,10 +2359,18 @@ msgstr "Es müssen 8 oder 16 bits_per_sample sein"
msgid "branch not in range"
msgstr "Zweig ist außerhalb der Reichweite"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "Puffer muss ein bytes-artiges Objekt sein"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "Die Puffergröße muss zum Format passen"
@@ -3363,6 +3392,10 @@ msgstr "Nicht genügend Argumente für den Formatierungs-String"
msgid "number of points must be at least 2"
msgstr "Die Anzahl der Punkte muss mindestens 2 betragen"
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3419,6 +3452,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "offset außerhalb der Grenzen"
@@ -3983,6 +4020,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "Fenster muss <= Intervall sein"
diff --git a/locale/el.po b/locale/el.po
index 7001c2aa2..104dff4ee 100644
--- a/locale/el.po
+++ b/locale/el.po
@@ -43,6 +43,10 @@ msgstr ""
msgid " File \"%q\", line %d"
msgstr ""
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr ""
@@ -850,6 +854,10 @@ msgstr ""
msgid "Error in regex"
msgstr ""
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1240,10 +1248,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1260,6 +1276,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1542,7 +1562,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2013,7 +2033,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2278,10 +2299,18 @@ msgstr ""
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr ""
@@ -3283,6 +3312,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3339,6 +3372,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr ""
@@ -3893,6 +3930,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index 45695665c..58634a597 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -48,6 +48,10 @@ msgstr " Archivo \"%q\""
msgid " File \"%q\", line %d"
msgstr " Archivo \"%q\", línea %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " salida:\n"
@@ -868,6 +872,10 @@ msgstr "El canal EXTINT ya está siendo utilizado"
msgid "Error in regex"
msgstr "Error en regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1261,10 +1269,18 @@ msgstr "'security_mode' no válido"
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "Voz inválida"
@@ -1281,6 +1297,10 @@ msgstr "Archivo wave inválido"
msgid "Invalid word/bit length"
msgstr "Tamaño no válido de palabra/bit"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "La llave debe tener 16, 24 o 32 bytes de longitud"
@@ -1569,7 +1589,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "Se acabaron los enchufes"
@@ -2063,8 +2083,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Error no manejado de ESP TLS %d %d %x %d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Fallo desconocido"
+#, c-format
+msgid "Unknown failure %d"
+msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2339,10 +2360,18 @@ msgstr "bits_per_sample debe ser 8 ó 16"
msgid "branch not in range"
msgstr "la rama no está dentro del rango"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
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 ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "el tamaño del buffer debe de coincidir con el formato"
@@ -3357,6 +3386,10 @@ msgstr "no suficientes argumentos para format string"
msgid "number of points must be at least 2"
msgstr "el número de puntos debe ser al menos 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "objeto '%q' no es tupla o lista"
@@ -3413,6 +3446,10 @@ msgstr "offset es demasiado grande"
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "offset fuera de límites"
@@ -3970,6 +4007,10 @@ msgstr "el tiempo de espera del perro guardián debe ser mayor a 0"
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 ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "la ventana debe ser <= intervalo"
@@ -4034,6 +4075,9 @@ msgstr "zi debe ser de tipo flotante"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi debe ser una forma (n_section,2)"
+#~ msgid "Unknown failure"
+#~ msgstr "Fallo desconocido"
+
#~ msgid "input argument must be an integer or a 2-tuple"
#~ msgstr "el argumento de entrada debe ser un entero o una tupla de par"
diff --git a/locale/fil.po b/locale/fil.po
index ddd5f3dfe..cd59ad213 100644
--- a/locale/fil.po
+++ b/locale/fil.po
@@ -42,6 +42,10 @@ msgstr " File \"%q\""
msgid " File \"%q\", line %d"
msgstr " File \"%q\", line %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " output:\n"
@@ -861,6 +865,10 @@ msgstr "Ginagamit na ang EXTINT channel"
msgid "Error in regex"
msgstr "May pagkakamali sa REGEX"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1255,10 +1263,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1275,6 +1291,10 @@ msgstr "May hindi tama sa wave file"
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1560,7 +1580,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2034,7 +2054,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2308,10 +2329,18 @@ msgstr "bits_per_sample ay dapat 8 o 16"
msgid "branch not in range"
msgstr "branch wala sa range"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "buffer ay dapat bytes-like object"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
#, fuzzy
msgid "buffer size must match format"
@@ -3330,6 +3359,10 @@ msgstr "kulang sa arguments para sa format string"
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3386,6 +3419,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
#, fuzzy
msgid "offset out of bounds"
@@ -3946,6 +3983,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/fr.po b/locale/fr.po
index ad0ed6e7a..1c4714825 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-13 16:07+0000\n"
+"PO-Revision-Date: 2021-01-17 12:55+0000\n"
"Last-Translator: Hugo Dahl <hugo@code-jedi.com>\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.4.1-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
@@ -52,6 +52,10 @@ msgstr " Fichier \"%q\""
msgid " File \"%q\", line %d"
msgstr " Fichier \"%q\", ligne %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " sortie :\n"
@@ -646,7 +650,7 @@ msgstr ""
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Cannot set value when direction is input."
msgstr ""
-"Impossible d'affecter une valeur quand la direction est entrentre ('input')."
+"Impossible d'affecter une valeur quand la direction est entrante ('input')."
#: ports/esp32s2/common-hal/busio/UART.c
#: ports/mimxrt10xx/common-hal/busio/UART.c
@@ -882,6 +886,10 @@ msgstr "Canal EXTINT déjà utilisé"
msgid "Error in regex"
msgstr "Erreur dans l'expression régulière"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1277,10 +1285,18 @@ msgstr "'security_mode' invalide"
msgid "Invalid size"
msgstr "Taille invalide"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr "État invalide"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "Voix invalide"
@@ -1297,6 +1313,10 @@ msgstr "Fichier WAVE invalide"
msgid "Invalid word/bit length"
msgstr "Longueur de mot / bit invalide"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "La clé doit comporter 16, 24 ou 32 octets"
@@ -1585,7 +1605,7 @@ msgstr "Timeout de l'opération"
msgid "Out of memory"
msgstr "Hors de mémoire"
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "Plus de sockets"
@@ -2085,8 +2105,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Erreur ESP TLS non gérée %d %d %x %d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Echec inconnu"
+#, c-format
+msgid "Unknown failure %d"
+msgstr "Échec inconnu %d"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2363,10 +2384,18 @@ msgstr "'bits_per_sample' doivent être 8 ou 16"
msgid "branch not in range"
msgstr "branche hors-bornes"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr "tampon est plus petit que la taille demandée"
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "le tampon doit être un objet bytes-like"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr "taille du tampon doit être un multiple de la taille de l'élement"
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "la taille du tampon doit correspondre au format"
@@ -3390,6 +3419,10 @@ msgstr "pas assez d'arguments pour la chaîne de format"
msgid "number of points must be at least 2"
msgstr "le nombre de points doit être d'au moins 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "l'objet '%q' n'est pas un tuple ou une list"
@@ -3446,6 +3479,10 @@ msgstr "offset est trop large"
msgid "offset must be >= 0"
msgstr "offset doit être >= 0"
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr "offset doit être non-négatif, et au plus la taille du tampon"
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "décalage hors limites"
@@ -4006,6 +4043,10 @@ msgstr "watchdog timeout doit être supérieur à 0"
msgid "width must be greater than zero"
msgstr "width doit être plus grand que zero"
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "la fenêtre (window) doit être <= intervalle (interval)"
@@ -4070,6 +4111,9 @@ msgstr "zi doit être de type float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi doit être de forme (n_section, 2)"
+#~ msgid "Unknown failure"
+#~ msgstr "Echec inconnu"
+
#~ msgid "Only one alarm.touch alarm can be set."
#~ msgstr "Seulement une alarme alarm.touch peut être réglée."
diff --git a/locale/hi.po b/locale/hi.po
index 618490b37..f9fa68f5c 100644
--- a/locale/hi.po
+++ b/locale/hi.po
@@ -43,6 +43,10 @@ msgstr ""
msgid " File \"%q\", line %d"
msgstr ""
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr ""
@@ -850,6 +854,10 @@ msgstr ""
msgid "Error in regex"
msgstr ""
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1240,10 +1248,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1260,6 +1276,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1542,7 +1562,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2013,7 +2033,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2278,10 +2299,18 @@ msgstr ""
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr ""
@@ -3283,6 +3312,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3339,6 +3372,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr ""
@@ -3893,6 +3930,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/it_IT.po b/locale/it_IT.po
index f9f77b20e..e6402f929 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -42,6 +42,10 @@ msgstr " File \"%q\""
msgid " File \"%q\", line %d"
msgstr " File \"%q\", riga %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " output:\n"
@@ -861,6 +865,10 @@ msgstr "Canale EXTINT già in uso"
msgid "Error in regex"
msgstr "Errore nella regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1257,10 +1265,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1278,6 +1294,10 @@ msgstr "File wave non valido"
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1565,7 +1585,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2046,7 +2066,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2314,10 +2335,18 @@ msgstr "i bit devono essere 7, 8 o 9"
msgid "branch not in range"
msgstr "argomento di chr() non è in range(256)"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
#, fuzzy
msgid "buffer size must match format"
@@ -3336,6 +3365,10 @@ msgstr "argomenti non sufficienti per la stringa di formattazione"
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3392,6 +3425,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
#, fuzzy
msgid "offset out of bounds"
@@ -3954,6 +3991,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/ja.po b/locale/ja.po
index 37d23f959..42c882e9a 100644
--- a/locale/ja.po
+++ b/locale/ja.po
@@ -48,6 +48,10 @@ msgstr " ファイル \"%q\""
msgid " File \"%q\", line %d"
msgstr " ファイル \"%q\", 行 %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " 出力:\n"
@@ -861,6 +865,10 @@ msgstr "EXTINTチャネルはすでに使用されています"
msgid "Error in regex"
msgstr "正規表現にエラーがあります"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1253,10 +1261,18 @@ msgstr "不正なsecurity_mode"
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "不正なボイス"
@@ -1273,6 +1289,10 @@ msgstr "不正なwaveファイル"
msgid "Invalid word/bit length"
msgstr "不正なワード/ビット長"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Keyの長さは、16, 24, 32バイトのいずれかでなければなりません"
@@ -1557,7 +1577,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2036,7 +2056,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2301,10 +2322,18 @@ msgstr "bits_per_sampleは8または16でなければなりません"
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "バッファはbytes-likeオブジェクトでなければなりません"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr ""
@@ -3311,6 +3340,10 @@ msgstr "書式化文字列への引数が足りません"
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "オブジェクト'%q'がタプルやリストでありません"
@@ -3367,6 +3400,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr ""
@@ -3924,6 +3961,10 @@ msgstr "watchdogのtimeoutは0以上でなければなりません"
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "windowはinterval以下でなければなりません"
diff --git a/locale/ko.po b/locale/ko.po
index b7fc29629..97de46fcd 100644
--- a/locale/ko.po
+++ b/locale/ko.po
@@ -44,6 +44,10 @@ msgstr " 파일 \"%q\""
msgid " File \"%q\", line %d"
msgstr " 파일 \"%q\", 라인 %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " 산출:\n"
@@ -853,6 +857,10 @@ msgstr ""
msgid "Error in regex"
msgstr "Regex에 오류가 있습니다."
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1243,10 +1251,18 @@ msgstr ""
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr ""
@@ -1263,6 +1279,10 @@ msgstr ""
msgid "Invalid word/bit length"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""
@@ -1545,7 +1565,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -2017,7 +2037,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2282,10 +2303,18 @@ msgstr "bits_per_sample은 8 또는 16이어야합니다."
msgid "branch not in range"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr ""
@@ -3287,6 +3316,10 @@ msgstr ""
msgid "number of points must be at least 2"
msgstr ""
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3343,6 +3376,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr ""
@@ -3897,6 +3934,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/nl.po b/locale/nl.po
index 52984373c..58cc8e603 100644
--- a/locale/nl.po
+++ b/locale/nl.po
@@ -46,6 +46,10 @@ msgstr " Bestand"
msgid " File \"%q\", line %d"
msgstr " Bestand \"%q\", regel %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " uitvoer:\n"
@@ -861,6 +865,10 @@ msgstr "EXTINT kanaal al in gebruik"
msgid "Error in regex"
msgstr "Fout in regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1254,10 +1262,18 @@ msgstr "Ongeldige security_mode"
msgid "Invalid size"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr ""
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr ""
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr ""
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "Ongeldige stem"
@@ -1274,6 +1290,10 @@ msgstr "Ongeldig wave bestand"
msgid "Invalid word/bit length"
msgstr "Ongeldig woord/bit lengte"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Sleutel moet 16, 24, of 32 bytes lang zijn"
@@ -1562,7 +1582,7 @@ msgstr ""
msgid "Out of memory"
msgstr ""
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "Geen sockets meer beschikbaar"
@@ -2055,8 +2075,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Niet behandelde ESP TLS fout %d %d %x %d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Onbekende fout"
+#, c-format
+msgid "Unknown failure %d"
+msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2331,10 +2352,18 @@ msgstr "bits_per_sample moet 8 of 16 zijn"
msgid "branch not in range"
msgstr "pad (branch) niet binnen bereik"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "buffer moet een byte-achtig object zijn"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "grootte van de buffer moet overeenkomen met het formaat"
@@ -3344,6 +3373,10 @@ msgstr "niet genoeg argumenten om string te formatteren"
msgid "number of points must be at least 2"
msgstr "aantal punten moet minimaal 2 zijn"
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "object '%q' is geen tuple of lijst"
@@ -3400,6 +3433,10 @@ msgstr "compensatie is te groot"
msgid "offset must be >= 0"
msgstr "compensatie moet groter of gelijk 0 zijn"
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "offset buiten bereik"
@@ -3957,6 +3994,10 @@ msgstr "watchdog time-out moet groter zijn dan 0"
msgid "width must be greater than zero"
msgstr "breedte moet groter dan nul zijn"
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "window moet <= interval zijn"
@@ -4021,6 +4062,9 @@ msgstr "zi moet van type float zijn"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi moet vorm (n_section, 2) hebben"
+#~ msgid "Unknown failure"
+#~ msgstr "Onbekende fout"
+
#~ msgid "input argument must be an integer or a 2-tuple"
#~ msgstr "invoerargument moet een integer of 2-tuple zijn"
diff --git a/locale/pl.po b/locale/pl.po
index 41eee9e74..14a57b4ea 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: 2020-12-02 20:29+0000\n"
+"PO-Revision-Date: 2021-01-20 02:40+0000\n"
"Last-Translator: Maciej Stankiewicz <tawezik@gmail.com>\n"
"Language-Team: pl\n"
"Language: pl\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
@@ -48,6 +48,10 @@ msgstr " Plik \"%q\""
msgid " File \"%q\", line %d"
msgstr " Plik \"%q\", linia %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr ""
+
#: main.c
msgid " output:\n"
msgstr " wyjście:\n"
@@ -770,7 +774,7 @@ msgstr "Nie można rozpocząć przerwania, RX jest zajęty"
#: shared-module/audiomp3/MP3Decoder.c
msgid "Couldn't allocate decoder"
-msgstr ""
+msgstr "Nie udało się przydzielić dekodera"
#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c
#: shared-module/audiomp3/MP3Decoder.c
@@ -861,6 +865,10 @@ msgstr "Kanał EXTINT w użyciu"
msgid "Error in regex"
msgstr "Błąd w regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr ""
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1070,7 +1078,7 @@ msgstr "Niewłaściwa wielkość bufora"
#: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c
msgid "Initialization failed due to lack of memory"
-msgstr ""
+msgstr "Inicjalizacja nie powiodła się z powodu braku pamięci"
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
msgid "Input taking too long"
@@ -1251,10 +1259,18 @@ msgstr "Nieprawidłowy security_mode"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid size"
+msgstr "Nieprawidłowy rozmiar"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
+msgstr "Nieprawidłowy stan"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
msgstr ""
#: shared-bindings/audiomixer/Mixer.c
@@ -1273,6 +1289,10 @@ msgstr "Zły plik wave"
msgid "Invalid word/bit length"
msgstr "Niepoprawna długość słowa/bitu"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr ""
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Klucz musi mieć długość 16, 24 lub 32 bajtów"
@@ -1554,9 +1574,9 @@ msgstr ""
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Out of memory"
-msgstr ""
+msgstr "Brak pamięci"
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr ""
@@ -1707,7 +1727,7 @@ msgstr "Obiekt tylko do odczytu"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Received response was invalid"
-msgstr ""
+msgstr "Otrzymana odpowiedź była nieprawidłowa"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
@@ -1723,7 +1743,7 @@ msgstr "Żądany tryb AES nie jest obsługiwany"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Requested resource not found"
-msgstr ""
+msgstr "Nie znaleziono żądanego zasobu"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
@@ -2027,7 +2047,8 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr ""
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
+#, c-format
+msgid "Unknown failure %d"
msgstr ""
#: ports/nrf/common-hal/_bleio/__init__.c
@@ -2298,10 +2319,18 @@ msgstr "bits_per_sample musi być 8 lub 16"
msgid "branch not in range"
msgstr "skok poza zakres"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr ""
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "bufor mysi być typu bytes"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr ""
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "wielkość bufora musi pasować do formatu"
@@ -3304,6 +3333,10 @@ msgstr "nie dość argumentów przy formatowaniu"
msgid "number of points must be at least 2"
msgstr "liczba punktów musi wynosić co najmniej 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr ""
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr ""
@@ -3360,6 +3393,10 @@ msgstr ""
msgid "offset must be >= 0"
msgstr ""
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr ""
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "offset poza zakresem"
@@ -3916,6 +3953,10 @@ msgstr ""
msgid "width must be greater than zero"
msgstr ""
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr ""
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index 64723c193..92d46a4cf 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-01-13 02:19+0000\n"
+"PO-Revision-Date: 2021-01-22 15:30+0000\n"
"Last-Translator: Wellington Terumi Uemura <wellingtonuemura@gmail.com>\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.4.1-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
@@ -50,6 +50,10 @@ msgstr " Arquivo \"%q\""
msgid " File \"%q\", line %d"
msgstr " Arquivo \"%q\", linha %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr " é do tipo %q\n"
+
#: main.c
msgid " output:\n"
msgstr " saída:\n"
@@ -877,6 +881,10 @@ msgstr "Canal EXTINT em uso"
msgid "Error in regex"
msgstr "Erro no regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr "Erro: Falha na vinculação"
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1270,10 +1278,18 @@ msgstr "O Security_mode é inválido"
msgid "Invalid size"
msgstr "Tamanho inválido"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr "Soquete inválido para o TLS"
+
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
msgstr "Estado inválido"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr "Uso inválido do soquete TLS"
+
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
msgstr "A voz é inválida"
@@ -1290,6 +1306,10 @@ msgstr "Aqruivo de ondas inválido"
msgid "Invalid word/bit length"
msgstr "O comprimento do bit/palavra são inválidos"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr "Problema na configuração do SO_REUSEADDR"
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "A chave deve ter 16, 24 ou 32 bytes de comprimento"
@@ -1577,7 +1597,7 @@ msgstr "A operação expirou"
msgid "Out of memory"
msgstr "Sem memória"
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "Sem soquetes"
@@ -2078,8 +2098,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Erro não tratado do ESP TLS %d %d %x %d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Falha desconhecida"
+#, c-format
+msgid "Unknown failure %d"
+msgstr "Falha desconhecida %d"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2355,10 +2376,18 @@ msgstr "bits_per_sample deve ser 8 ou 16"
msgid "branch not in range"
msgstr "ramo fora do alcance"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr "o tamanho do buffer é menor do que o tamanho que foi solicitado"
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "o buffer deve ser um objeto como bytes"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr "o tamanho do buffer deve ser um múltiplo do tamanho do elemento"
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "o tamanho do buffer deve coincidir com o formato"
@@ -3375,6 +3404,10 @@ msgstr "argumentos insuficientes para o formato da string"
msgid "number of points must be at least 2"
msgstr "a quantidade dos pontos deve ser pelo menos 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr "objeto "
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "o objeto '%q' não é uma tupla ou uma lista"
@@ -3431,6 +3464,10 @@ msgstr "o offset é muito grande"
msgid "offset must be >= 0"
msgstr "o offset deve ser >= 0"
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr "o offset deve ser positivo e não maior do que o comprimento do buffer"
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "desvio fora dos limites"
@@ -3992,6 +4029,10 @@ msgstr "o tempo limite do watchdog deve ser maior que 0"
msgid "width must be greater than zero"
msgstr "a largura deve ser maior que zero"
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr "o wifi não está ativo"
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "a janela deve ser <= intervalo"
@@ -4056,6 +4097,9 @@ msgstr "zi deve ser de um tipo float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi deve estar na forma (n_section, 2)"
+#~ msgid "Unknown failure"
+#~ msgstr "Falha desconhecida"
+
#~ msgid "Only one alarm.touch alarm can be set."
#~ msgstr "Apenas um alarme alarm.touch pode ser definido."
diff --git a/locale/sv.po b/locale/sv.po
index 477664972..c3b55d5a0 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-01-05 21:03+0000\n"
+"PO-Revision-Date: 2021-01-25 19:32+0000\n"
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\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.4.1-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
@@ -50,6 +50,10 @@ msgstr " Filen \"%q\""
msgid " File \"%q\", line %d"
msgstr " Fil \"%q\", rad %d"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr " är av typen %q\n"
+
#: main.c
msgid " output:\n"
msgstr " utdata:\n"
@@ -123,7 +127,7 @@ msgstr "%q() kräver %d positionsargument men %d gavs"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
#, c-format
msgid "%s error 0x%x"
-msgstr ""
+msgstr "%s fel 0x%x"
#: py/argcheck.c
msgid "'%q' argument required"
@@ -289,7 +293,7 @@ msgstr "3-arguments pow() stöds inte"
#: shared-module/msgpack/__init__.c
msgid "64 bit types"
-msgstr ""
+msgstr "64-bitars typer"
#: ports/atmel-samd/common-hal/countio/Counter.c
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
@@ -555,7 +559,7 @@ msgstr "CBC-block måste vara multiplar om 16 byte"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "CRC or checksum was invalid"
-msgstr ""
+msgstr "CRC eller checksumma var ogiltig"
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
@@ -866,6 +870,10 @@ msgstr "EXTINT-kanalen används redan"
msgid "Error in regex"
msgstr "Fel i regex"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr "Fel: Bind misslyckades"
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -1014,7 +1022,7 @@ msgstr "Funktion kräver lås"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Generic Failure"
-msgstr ""
+msgstr "Generiskt fel"
#: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
@@ -1256,11 +1264,19 @@ msgstr "Ogiltigt säkerhetsläge"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid size"
-msgstr ""
+msgstr "Ogiltig storlek"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr "Ogiltig socket för TLS"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
-msgstr ""
+msgstr "Ogiltigt tillstånd"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr "Ogiltig användning av TLS Socket"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
@@ -1278,6 +1294,10 @@ msgstr "Ogiltig wave-fil"
msgid "Invalid word/bit length"
msgstr "Ogiltig word-/bitlängd"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr "Misslyckades att sätta SO_REUSEADDR"
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "Nyckeln måste vara 16, 24 eller 32 byte lång"
@@ -1304,7 +1324,7 @@ msgstr "Length måste vara positiv"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "MAC address was invalid"
-msgstr ""
+msgstr "MAC-adressen var ogiltig"
#: shared-module/bitbangio/SPI.c
msgid "MISO pin init failed."
@@ -1540,7 +1560,7 @@ msgstr ""
#: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c
msgid "Only one TouchAlarm can be set in deep sleep."
-msgstr ""
+msgstr "Endast ett TouchAlarm kan ställas in för djupsömn."
#: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
msgid "Only one alarm.time alarm can be set."
@@ -1556,17 +1576,17 @@ msgstr "Endast raw int stöds för ip"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
-msgstr ""
+msgstr "Operation eller funktion stöds inte"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation timed out"
-msgstr ""
+msgstr "Åtgärden orsakade timeout"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Out of memory"
-msgstr ""
+msgstr "Slut på minne"
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "Slut på sockets"
@@ -1576,7 +1596,7 @@ msgstr "Översampling måste vara multipel av 8."
#: shared-bindings/audiobusio/PDMIn.c
msgid "PDMIn not available"
-msgstr ""
+msgstr "PDMIn inte tillgänglig"
#: shared-bindings/pwmio/PWMOut.c
msgid ""
@@ -1598,7 +1618,7 @@ msgstr "ParallelBus stöds ännu inte"
#: ports/esp32s2/common-hal/audiobusio/__init__.c
msgid "Peripheral in use"
-msgstr ""
+msgstr "Periferi i bruk"
#: py/moduerrno.c
msgid "Permission denied"
@@ -1728,7 +1748,7 @@ msgstr "Skrivskyddat objekt"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Received response was invalid"
-msgstr ""
+msgstr "Mottaget svar var ogiltigt"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
@@ -1744,7 +1764,7 @@ msgstr "Det begärda AES-läget stöds inte"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Requested resource not found"
-msgstr ""
+msgstr "Begärd resurs hittades inte"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
@@ -2058,8 +2078,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Ej hanterat ESP TLS-fel %d-%d-%x-%d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Okänt fel"
+#, c-format
+msgid "Unknown failure %d"
+msgstr "Okänt fel %d"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2130,7 +2151,7 @@ msgstr "Värdets längd > max_length"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Version was invalid"
-msgstr ""
+msgstr "Versionen var ogiltig"
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
@@ -2331,10 +2352,18 @@ msgstr "bits_per_sample måste vara 8 eller 16"
msgid "branch not in range"
msgstr "branch utanför räckvidd"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr "bufferten är mindre än begärd storlek"
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "buffer måste vara en byte-liknande objekt"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr "buffertstorlek måste vara en multipel av elementstorlek"
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "buffertstorleken måste matcha formatet"
@@ -2544,7 +2573,7 @@ msgstr "circle kan endast registreras i en förälder"
#: shared-bindings/msgpack/ExtType.c
msgid "code outside range 0~127"
-msgstr ""
+msgstr "kod utanför intervallet 0~127"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
@@ -2632,7 +2661,7 @@ msgstr "standard \"except\" måste ligga sist"
#: shared-bindings/msgpack/__init__.c
msgid "default is not a function"
-msgstr ""
+msgstr "default är inte en funktion"
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
@@ -2738,7 +2767,7 @@ msgstr "förväntar nyckel:värde för dict"
#: shared-bindings/msgpack/__init__.c
msgid "ext_hook is not a function"
-msgstr ""
+msgstr "ext_hook är inte en funktion"
#: py/argcheck.c
msgid "extra keyword arguments given"
@@ -3277,7 +3306,7 @@ msgstr "ingen bindning för ickelokal hittad"
#: shared-module/msgpack/__init__.c
msgid "no default packer"
-msgstr ""
+msgstr "ingen standardpackare"
#: py/builtinimport.c
msgid "no module named '%q'"
@@ -3344,6 +3373,10 @@ msgstr "inte tillräckligt med argument för formatsträng"
msgid "number of points must be at least 2"
msgstr "antal punkter måste vara minst 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr "objekt "
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "objektet '%q' är inte en tuple eller list"
@@ -3400,6 +3433,10 @@ msgstr "offset är för stor"
msgid "offset must be >= 0"
msgstr "offset måste vara >= 0"
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr "offset måste vara icke-negativt och inte längre än buffertlängd"
+
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
msgstr "offset utanför gränserna"
@@ -3619,7 +3656,7 @@ msgstr "shape måste vara en tuple"
#: shared-module/msgpack/__init__.c
msgid "short read"
-msgstr ""
+msgstr "kort läsning"
#: py/objstr.c
msgid "sign not allowed in string format specifier"
@@ -3957,6 +3994,10 @@ msgstr "watchdog timeout måste vara större än 0"
msgid "width must be greater than zero"
msgstr "width måste vara större än noll"
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr "wifi är inte aktiverat"
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "window måste vara <= interval"
@@ -3995,7 +4036,7 @@ msgstr "x-värde utanför intervall"
#: ports/esp32s2/common-hal/audiobusio/__init__.c
msgid "xTaskCreate failed"
-msgstr ""
+msgstr "xTaskCreate misslyckades"
#: shared-bindings/displayio/Shape.c
msgid "y should be an int"
@@ -4021,6 +4062,9 @@ msgstr "zi måste vara av typ float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi måste vara i formen (n_section, 2)"
+#~ msgid "Unknown failure"
+#~ msgstr "Okänt fel"
+
#~ msgid "Only one alarm.touch alarm can be set."
#~ msgstr "Endast ett larm av typ alarm.touch kan ställas in."
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index d9a750b34..c2ff04044 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: 2020-11-19 01:28+0000\n"
+"PO-Revision-Date: 2021-01-25 19:32+0000\n"
"Last-Translator: hexthat <hexthat@gmail.com>\n"
"Language-Team: Chinese Hanyu Pinyin\n"
"Language: zh_Latn_pinyin\n"
@@ -15,19 +15,23 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.5-dev\n"
#: main.c
msgid ""
"\n"
"Code done running.\n"
msgstr ""
+"\n"
+"Dàimǎ yùnxíng wánbì.\n"
#: main.c
msgid ""
"\n"
"Code stopped by auto-reload.\n"
msgstr ""
+"\n"
+"zì dòng chóng xīn jiā zǎi tíng zhǐ de dài mǎ.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -47,6 +51,10 @@ msgstr " Wénjiàn \"%q\""
msgid " File \"%q\", line %d"
msgstr " Wénjiàn \"%q\", dì %d xíng"
+#: py/builtinhelp.c
+msgid " is of type %q\n"
+msgstr " shì %q lèi xíng\n"
+
#: main.c
msgid " output:\n"
msgstr " shūchū:\n"
@@ -121,7 +129,7 @@ msgstr "%q() cǎiyòng %d wèizhì cānshù, dàn gěi chū %d"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
#, c-format
msgid "%s error 0x%x"
-msgstr ""
+msgstr "%s cuò wù 0x%x"
#: py/argcheck.c
msgid "'%q' argument required"
@@ -287,7 +295,7 @@ msgstr "bù zhīchí 3-arg pow ()"
#: shared-module/msgpack/__init__.c
msgid "64 bit types"
-msgstr ""
+msgstr "64 wèi lèi xíng"
#: ports/atmel-samd/common-hal/countio/Counter.c
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
@@ -553,7 +561,7 @@ msgstr "CBC kuài bì xū shì 16 zì jié de bèi shù"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "CRC or checksum was invalid"
-msgstr ""
+msgstr "CRC huò jiào yàn hé wú xiào"
#: py/objtype.c
msgid "Call super().__init__() before accessing native object."
@@ -561,15 +569,17 @@ msgstr "Zài fǎngwèn běn jī wùjiàn zhīqián diàoyòng super().__init__()
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on RTC IO from deep sleep."
-msgstr ""
+msgstr "zhǐ néng zài RTC Io shàng cóng shēn dù shuì mián zhōng bào jǐng."
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on one low pin while others alarm high from deep sleep."
msgstr ""
+"Zhǐ néng zài yīgè dī diàn píng yǐn jiǎo shàng fāchū jǐngbào, ér qítā yǐn "
+"jiǎo cóng shēndù shuìmián zhōng fāchū gāo diàn píng jǐngbào."
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on two low pins from deep sleep."
-msgstr ""
+msgstr "zhǐ néng cóng shēn dù shuì mián zhōng bào jǐng liǎng gè dī yǐn jiǎo."
#: ports/nrf/common-hal/_bleio/Characteristic.c
msgid "Can't set CCCD on local Characteristic"
@@ -605,7 +615,7 @@ msgstr "Wúfǎ shūchū tóng yīgè yǐn jiǎo shàng de liǎng gè píndào"
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot pull on input-only pin."
-msgstr ""
+msgstr "wú fǎ lā dòng jǐn shū rù yǐn jiǎo."
#: shared-module/bitbangio/SPI.c
msgid "Cannot read without MISO pin."
@@ -652,7 +662,7 @@ msgstr "Wúfǎ gēnggǎi yǐ zài shǐyòng de jìshí qì shàng de pínlǜ"
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge. Only level."
-msgstr ""
+msgstr "wú fǎ zài yǐn jiǎo biān yuán huàn xǐng. jǐn jí bié."
#: shared-module/bitbangio/SPI.c
msgid "Cannot write without MOSI pin."
@@ -859,6 +869,10 @@ msgstr "EXTINT píndào yǐjīng shǐyòng"
msgid "Error in regex"
msgstr "Zhèngzé biǎodá shì cuòwù"
+#: shared-bindings/socketpool/Socket.c
+msgid "Error: Failure to bind"
+msgstr "cuò wù: bǎng dìng shī bài"
+
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
#: shared-bindings/busio/SPI.c shared-bindings/microcontroller/Pin.c
#: shared-bindings/neopixel_write/__init__.c
@@ -894,7 +908,7 @@ msgstr "Qídài yīgè dìzhǐ"
#: shared-bindings/alarm/__init__.c
msgid "Expected an alarm"
-msgstr ""
+msgstr "yù qī yǒu jǐng bào"
#: shared-module/_pixelbuf/PixelBuf.c
#, c-format
@@ -911,7 +925,7 @@ msgstr "FFT jǐn wéi ndarrays dìng yì"
#: extmod/ulab/code/fft/fft.c
msgid "FFT is implemented for linear arrays only"
-msgstr ""
+msgstr "FFT jǐn shì yòng yú xiàn xìng zhèn liè"
#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Failed SSL handshake"
@@ -985,7 +999,7 @@ msgstr "guò lǜ qì tài fù zá"
#: ports/esp32s2/common-hal/dualbank/__init__.c
msgid "Firmware image is invalid"
-msgstr ""
+msgstr "gù jiàn yìng xiàng wú xiào"
#: ports/cxd56/common-hal/camera/Camera.c
msgid "Format not supported"
@@ -1007,7 +1021,7 @@ msgstr "Hánshù xūyào suǒdìng"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Generic Failure"
-msgstr ""
+msgstr "tōng yòng gù zhàng"
#: shared-bindings/displayio/Display.c
#: shared-bindings/displayio/EPaperDisplay.c
@@ -1047,7 +1061,7 @@ msgstr "I2SOut bù kě yòng"
#: 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 bù zhī chí shuì mián zhōng de nèi bù shàng lā"
#: shared-bindings/aesio/aes.c
#, c-format
@@ -1135,7 +1149,7 @@ msgstr "Wúxiào de PWM pínlǜ"
#: ports/esp32s2/common-hal/analogio/AnalogIn.c
msgid "Invalid Pin"
-msgstr ""
+msgstr "wú xiào yǐn jiǎo"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
#: py/moduerrno.c shared-module/rgbmatrix/RGBMatrix.c
@@ -1249,11 +1263,19 @@ msgstr "Ānquán móshì wúxiào"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid size"
-msgstr ""
+msgstr "dà xiǎo wú xiào"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid socket for TLS"
+msgstr "TLS de chā zuò wú xiào"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Invalid state"
-msgstr ""
+msgstr "wú xiào zhuàng tài"
+
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Invalid use of TLS Socket"
+msgstr "TLS tào jiē zì de wú xiào shǐ yòng"
#: shared-bindings/audiomixer/Mixer.c
msgid "Invalid voice"
@@ -1271,6 +1293,10 @@ msgstr "Wúxiào de làng làngcháo wénjiàn"
msgid "Invalid word/bit length"
msgstr "Wúxiào de zì/wèi chángdù"
+#: ports/esp32s2/common-hal/socketpool/Socket.c
+msgid "Issue setting SO_REUSEADDR"
+msgstr "wèn tí shè zhì SO_REUSEADDR"
+
#: shared-bindings/aesio/aes.c
msgid "Key must be 16, 24, or 32 bytes long"
msgstr "mì yào bì xū wéi 16, 24 huò 32 zì jié cháng"
@@ -1297,7 +1323,7 @@ msgstr "Chángdù bìxū shìfēi fùshù"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "MAC address was invalid"
-msgstr ""
+msgstr "MAC dì zhǐ wú xiào"
#: shared-module/bitbangio/SPI.c
msgid "MISO pin init failed."
@@ -1347,7 +1373,7 @@ msgstr "bì xū shǐ yòng 6 RGB yǐn jiǎo de bèi shù, ér bù shì %d"
#: ports/esp32s2/common-hal/nvm/ByteArray.c
msgid "NVS Error"
-msgstr ""
+msgstr "NVS cuò wù"
#: py/parse.c
msgid "Name too long"
@@ -1370,7 +1396,7 @@ msgstr "Wèi zhǎodào DMA píndào"
#: shared-module/adafruit_bus_device/I2CDevice.c
#, c-format
msgid "No I2C device at address: %x"
-msgstr ""
+msgstr "dì zhǐ wú I2C shè bèi: %x"
#: ports/esp32s2/common-hal/busio/SPI.c ports/mimxrt10xx/common-hal/busio/SPI.c
#: ports/stm/common-hal/busio/SPI.c
@@ -1511,7 +1537,7 @@ msgstr "Jǐn zhīchí IPv4 dìzhǐ"
#: ports/esp32s2/common-hal/socketpool/SocketPool.c
msgid "Only IPv4 sockets supported"
-msgstr ""
+msgstr "jǐn zhī chí IPv4 tào jiē zì"
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
@@ -1532,11 +1558,11 @@ msgstr ""
#: ports/esp32s2/common-hal/alarm/touch/TouchAlarm.c
msgid "Only one TouchAlarm can be set in deep sleep."
-msgstr ""
+msgstr "zhǐ yǒu yí gè chù mō bì kě yǐ shè zhì zài shēn dù shuì mián."
#: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
msgid "Only one alarm.time alarm can be set."
-msgstr ""
+msgstr "zhǐ néng shè zhì yí gè bào jǐng."
#: shared-module/displayio/ColorConverter.c
msgid "Only one color can be transparent at a time"
@@ -1548,17 +1574,17 @@ msgstr "Ip jǐn zhīchí raw int"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation or feature not supported"
-msgstr ""
+msgstr "bù zhī chí cāo zuò huò gōng néng"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Operation timed out"
-msgstr ""
+msgstr "cāo zuò yǐ fēn shí"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Out of memory"
-msgstr ""
+msgstr "nèi cún bù zú"
-#: ports/esp32s2/common-hal/socketpool/SocketPool.c
+#: ports/esp32s2/common-hal/socketpool/Socket.c
msgid "Out of sockets"
msgstr "tào jiē zì wài"
@@ -1568,7 +1594,7 @@ msgstr "Guò cǎiyàng bìxū shì 8 de bèishù."
#: shared-bindings/audiobusio/PDMIn.c
msgid "PDMIn not available"
-msgstr ""
+msgstr "PDMIn bù kě yòng"
#: shared-bindings/pwmio/PWMOut.c
msgid ""
@@ -1589,7 +1615,7 @@ msgstr "Shàng bù zhīchí ParallelBus"
#: ports/esp32s2/common-hal/audiobusio/__init__.c
msgid "Peripheral in use"
-msgstr ""
+msgstr "shǐ yòng zhōng de wài shè"
#: py/moduerrno.c
msgid "Permission denied"
@@ -1658,11 +1684,13 @@ msgstr "Qiánzhuì huǎnchōng qū bìxū zài duī shàng"
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n"
-msgstr ""
+msgstr "àn rèn hé jiàn jìn rù REPL. shǐ yòng CTRL-D zhòng xīn jiā zǎi .\n"
#: main.c
msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n"
msgstr ""
+"jiǎ zhuāng shēn dù shuì mián , zhí dào bào jǐng , CTRL-C huò wén jiàn xiě "
+"rù .\n"
#: shared-bindings/digitalio/DigitalInOut.c
msgid "Pull not used when direction is output."
@@ -1714,7 +1742,7 @@ msgstr "Zhǐ dú duìxiàng"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Received response was invalid"
-msgstr ""
+msgstr "shōu dào de xiǎng yìng wú xiào"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
@@ -1730,7 +1758,7 @@ msgstr "Qǐngqiú de AES móshì bù shòu zhīchí"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Requested resource not found"
-msgstr ""
+msgstr "wèi zhǎo dào qǐng qiú de zī yuán"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "Right channel unsupported"
@@ -1842,7 +1870,7 @@ msgstr "Dìngyì zhìshǎo yīgè UART yǐn jiǎo"
#: shared-bindings/alarm/time/TimeAlarm.c
msgid "Supply one of monotonic_time or epoch_time"
-msgstr ""
+msgstr "tí gòng qí zhōng yī monotonic_time huò epoch_time"
#: shared-bindings/gnss/GNSS.c
msgid "System entry must be gnss.SatelliteSystem"
@@ -1916,7 +1944,7 @@ msgstr "Píng pū kuāndù bìxū huàfēn wèi tú kuāndù"
#: shared-bindings/alarm/time/TimeAlarm.c
msgid "Time is in the past."
-msgstr ""
+msgstr "shí jiān yǐ jīng guò qù."
#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
@@ -2031,7 +2059,7 @@ msgstr "Wúfǎ xiě rù nvm."
#: shared-bindings/alarm/SleepMemory.c
msgid "Unable to write to sleep_memory."
-msgstr ""
+msgstr "wú fǎ xiě rù sleep_memory。"
#: ports/nrf/common-hal/_bleio/UUID.c
msgid "Unexpected nrfx uuid type"
@@ -2043,8 +2071,9 @@ msgid "Unhandled ESP TLS error %d %d %x %d"
msgstr "Wèi chǔlǐ de ESP TLS cuòwù %d %d %x %d"
#: shared-bindings/wifi/Radio.c
-msgid "Unknown failure"
-msgstr "Wèizhī gùzhàng"
+#, c-format
+msgid "Unknown failure %d"
+msgstr "wèi zhī gù zhàng %d"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@@ -2101,7 +2130,7 @@ msgstr "Bù zhīchí de lādòng zhí."
#: ports/esp32s2/common-hal/dualbank/__init__.c
msgid "Update Failed"
-msgstr ""
+msgstr "gēng xīn shī bài"
#: ports/nrf/common-hal/_bleio/Characteristic.c
#: ports/nrf/common-hal/_bleio/Descriptor.c
@@ -2115,7 +2144,7 @@ msgstr "Zhí chángdù > zuìdà chángdù"
#: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c
msgid "Version was invalid"
-msgstr ""
+msgstr "bǎn běn wú xiào"
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
@@ -2172,7 +2201,7 @@ msgstr "WiFi mìmǎ bìxū jiè yú 8 dào 63 gè zìfú zhī jiān"
#: main.c
msgid "Woken up by alarm.\n"
-msgstr ""
+msgstr "bèi jǐng bào chǎo xǐng.\n"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Writes not supported on Characteristic"
@@ -2229,7 +2258,7 @@ msgstr "argsort cānshù bìxū shì ndarray"
#: extmod/ulab/code/numerical/numerical.c
msgid "argsort is not implemented for flattened arrays"
-msgstr ""
+msgstr "wèi wéi pīn hé shù zǔ shí xiàn argsort"
#: py/runtime.c
msgid "argument has wrong type"
@@ -2254,7 +2283,7 @@ msgstr "cānshù bìxū shì ndarrays"
#: extmod/ulab/code/ndarray.c
msgid "array and index length must be equal"
-msgstr ""
+msgstr "shù zǔ hé suǒ yǐn cháng dù bì xū xiāng děng"
#: py/objarray.c shared-bindings/alarm/SleepMemory.c
#: shared-bindings/nvm/ByteArray.c
@@ -2263,7 +2292,7 @@ msgstr "yòu cè xūyào shùzǔ/zì jié"
#: extmod/ulab/code/numerical/numerical.c
msgid "attempt to get (arg)min/(arg)max of empty sequence"
-msgstr ""
+msgstr "cháng shì huò qǔ (arg) zuì xiǎo zhí /(arg) zuì dà kōng xù liè"
#: extmod/ulab/code/numerical/numerical.c
msgid "attempt to get argmin/argmax of an empty sequence"
@@ -2275,15 +2304,15 @@ msgstr "shǔxìng shàngwèi zhīchí"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis is out of bounds"
-msgstr ""
+msgstr "zhóu chāo chū biān jiè"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis must be None, or an integer"
-msgstr ""
+msgstr "zhóu bì xū wéi \" wú \" huò zhěng shù"
#: extmod/ulab/code/numerical/numerical.c
msgid "axis too long"
-msgstr ""
+msgstr "zhóu tài cháng"
#: py/builtinevex.c
msgid "bad compile mode"
@@ -2317,10 +2346,18 @@ msgstr "měi jiàn yàngběn bìxū wèi 8 huò 16"
msgid "branch not in range"
msgstr "fēnzhī bùzài fànwéi nèi"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer is smaller than requested size"
+msgstr "huǎn chōng qū xiǎo yú qǐng qiú de dà xiǎo"
+
#: shared-bindings/audiocore/RawSample.c
msgid "buffer must be a bytes-like object"
msgstr "huǎnchōng qū bìxū shì zì jié lèi duìxiàng"
+#: extmod/ulab/code/ulab_create.c
+msgid "buffer size must be a multiple of element size"
+msgstr "huǎn chōng qū dà xiǎo bì xū shì yuán sù dà xiǎo de bèi shù"
+
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
msgstr "huǎnchōng qū dàxiǎo bìxū pǐpèi géshì"
@@ -2488,7 +2525,7 @@ msgstr "wúfǎ cóng shǒudòng zìduàn guīgé qiēhuàn dào zìdòng zìduà
#: extmod/ulab/code/ndarray_operators.c
msgid "cannot cast output with casting rule"
-msgstr ""
+msgstr "wú fǎ shǐ yòng qiáng zhì zhuǎn huàn guī zé qiáng zhì zhuǎn huàn shū chū"
#: py/objtype.c
msgid "cannot create '%q' instances"
@@ -2528,7 +2565,7 @@ msgstr "quānzi zhǐ néng zài yī wèi jiāzhǎng zhōng zhùcè"
#: shared-bindings/msgpack/ExtType.c
msgid "code outside range 0~127"
-msgstr ""
+msgstr "dài mǎ chāo chū fàn wéi 0~127"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
@@ -2595,7 +2632,7 @@ msgstr "wúfǎ quèdìng SD kǎ bǎnběn"
#: extmod/ulab/code/numerical/numerical.c
msgid "cross is defined for 1D arrays of length 3"
-msgstr ""
+msgstr "duì yú cháng dù wéi 3 de 1D shù zǔ dìng yì cross"
#: extmod/ulab/code/approx/approx.c
msgid "data must be iterable"
@@ -2607,7 +2644,7 @@ msgstr "shùjù chángdù bìxū xiāngděng"
#: extmod/ulab/code/ndarray.c
msgid "data type not understood"
-msgstr ""
+msgstr "wèi lǐ jiě de shù jù lèi xíng"
#: py/parsenum.c
msgid "decimal numbers not supported"
@@ -2619,7 +2656,7 @@ msgstr "mòrèn 'except' bìxū shì zuìhòu yīgè"
#: shared-bindings/msgpack/__init__.c
msgid "default is not a function"
-msgstr ""
+msgstr "mò rèn zhí bú shì hán shù"
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
@@ -2646,7 +2683,7 @@ msgstr "bùtóng de cānshù bìxū shì ndarray"
#: extmod/ulab/code/numerical/numerical.c
msgid "differentiation order out of range"
-msgstr ""
+msgstr "chā yì shùn xù fàn wéi"
#: py/modmath.c py/objfloat.c py/objint_longlong.c py/objint_mpz.c py/runtime.c
#: shared-bindings/math/__init__.c
@@ -2679,7 +2716,7 @@ msgstr "jiéwěi_x yīnggāi shì yīgè zhěngshù"
#: shared-bindings/alarm/time/TimeAlarm.c
msgid "epoch_time not supported on this board"
-msgstr ""
+msgstr "epoch_time bǎn bù zhī chí cǐ bǎn běn"
#: ports/nrf/common-hal/busio/UART.c
#, c-format
@@ -2724,7 +2761,7 @@ msgstr "qídài guānjiàn: Zìdiǎn de jiàzhí"
#: shared-bindings/msgpack/__init__.c
msgid "ext_hook is not a function"
-msgstr ""
+msgstr "ext_hook bú shì hán shù"
#: py/argcheck.c
msgid "extra keyword arguments given"
@@ -2773,7 +2810,7 @@ msgstr "dì yīgè cānshù bìxū shì yī gè hánshù"
#: extmod/ulab/code/ulab_create.c
msgid "first argument must be a tuple of ndarrays"
-msgstr ""
+msgstr "dì yī gè cān shù bì xū shì yí gè yuán zǔ ndarrays"
#: extmod/ulab/code/ndarray.c
msgid "first argument must be an iterable"
@@ -2830,7 +2867,7 @@ msgstr "hánshù zài jiàngé mòwěi jùyǒu xiāngtóng de fúhào"
#: extmod/ulab/code/ndarray.c
msgid "function is defined for ndarrays only"
-msgstr ""
+msgstr "hán shù jǐn wéi ndarrays dìng yì"
#: py/argcheck.c
#, c-format
@@ -2926,11 +2963,11 @@ msgstr "nèi lián jíhé bìxū shì yīgè hánshù"
#: extmod/ulab/code/ndarray.c
msgid "input and output shapes are not compatible"
-msgstr ""
+msgstr "shū rù hé shū chū xíng zhuàng bù jiān róng"
#: extmod/ulab/code/ulab_create.c
msgid "input argument must be an integer, a tuple, or a list"
-msgstr ""
+msgstr "shū rù cān shù bì xū shì zhěng shù, yuán zǔ huò liè biǎo"
#: extmod/ulab/code/fft/fft.c
msgid "input array length must be power of 2"
@@ -2938,7 +2975,7 @@ msgstr "shūrù shùzǔ de chángdù bìxū shì 2 de mì"
#: extmod/ulab/code/ulab_create.c
msgid "input arrays are not compatible"
-msgstr ""
+msgstr "shū rù shù zǔ bù jiān róng"
#: extmod/ulab/code/poly/poly.c
msgid "input data must be an iterable"
@@ -2954,19 +2991,19 @@ msgstr "shūrù jǔzhèn shì qíyì de"
#: extmod/ulab/code/user/user.c
msgid "input must be a dense ndarray"
-msgstr ""
+msgstr "shū rù bì xū shì mì jí de ndarray"
#: extmod/ulab/code/ulab_create.c
msgid "input must be a tensor of rank 2"
-msgstr ""
+msgstr "shū rù bì xū shì děng jí 2 de zhāng liàng"
#: extmod/ulab/code/ulab_create.c extmod/ulab/code/user/user.c
msgid "input must be an ndarray"
-msgstr ""
+msgstr "shū rù bì xū shì ndarray"
#: extmod/ulab/code/filter/filter.c
msgid "input must be one-dimensional"
-msgstr ""
+msgstr "shū rù bì xū shì yì wéi de"
#: extmod/ulab/code/linalg/linalg.c
msgid "input must be square matrix"
@@ -2982,7 +3019,7 @@ msgstr "shūrù xiàngliàng de chángdù bìxū xiāngděng"
#: extmod/ulab/code/poly/poly.c
msgid "inputs are not iterable"
-msgstr ""
+msgstr "shū rù bù kě yí dòng"
#: py/parsenum.c
msgid "int() arg 2 must be >= 2 and <= 36"
@@ -3056,7 +3093,7 @@ msgstr "wúxiào de hàomǎ yǔfǎ"
#: ports/esp32s2/common-hal/alarm/pin/__init__.c
msgid "io must be rtc io"
-msgstr ""
+msgstr "IO bì xū shì RTC IO"
#: py/objtype.c
msgid "issubclass() arg 1 must be a class"
@@ -3155,11 +3192,11 @@ msgstr "Dāng gùdìng chángdù wèi %s shí, zuìdà chángdù bìxū wèi 0-%
#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c
msgid "max_length must be >= 0"
-msgstr ""
+msgstr "zuì dà cháng dù bì xū >= 0"
#: extmod/ulab/code/ndarray.c
msgid "maximum number of dimensions is 4"
-msgstr ""
+msgstr "zuì dà chǐ cùn shù wéi 4"
#: py/runtime.c
msgid "maximum recursion depth exceeded"
@@ -3175,7 +3212,7 @@ msgstr "maxiter yìng wéi > 0"
#: extmod/ulab/code/numerical/numerical.c
msgid "median argument must be an ndarray"
-msgstr ""
+msgstr "zhōng wèi shù cān shù bì xū shì ndarray"
#: py/runtime.c
#, c-format
@@ -3261,7 +3298,7 @@ msgstr "zhǎo bù dào fēi běndì de bǎng dìng"
#: shared-module/msgpack/__init__.c
msgid "no default packer"
-msgstr ""
+msgstr "wú mò rèn bāo zhuāng jī"
#: py/builtinimport.c
msgid "no module named '%q'"
@@ -3302,15 +3339,15 @@ msgstr "guānjiàn zì cānshù zhīhòu de fēi guānjiàn zì cānshù"
#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "non-zero timeout must be > 0.01"
-msgstr ""
+msgstr "fēi líng chāo shí bì xū > 0.01"
#: shared-bindings/_bleio/Adapter.c
msgid "non-zero timeout must be >= interval"
-msgstr ""
+msgstr "fēi líng chāo shí bì xū wéi >= jiàn gé"
#: extmod/ulab/code/linalg/linalg.c
msgid "norm is defined for 1D and 2D arrays"
-msgstr ""
+msgstr "wéi 1D hé 2D shù zǔ dìng yì guī fàn"
#: shared-bindings/_bleio/UUID.c
msgid "not a 128-bit UUID"
@@ -3328,6 +3365,10 @@ msgstr "géshì zìfú chuàn cān shǔ bùzú"
msgid "number of points must be at least 2"
msgstr "diǎnshù bìxū zhìshǎo wèi 2"
+#: py/builtinhelp.c
+msgid "object "
+msgstr "duì xiàng "
+
#: py/obj.c
msgid "object '%q' is not a tuple or list"
msgstr "duìxiàng '%q' bùshì yuán zǔ huò lièbiǎo"
@@ -3378,11 +3419,15 @@ msgstr "jīshù zìfú chuàn"
#: extmod/ulab/code/ulab_create.c
msgid "offset is too large"
-msgstr ""
+msgstr "piān yí tài dà"
#: shared-bindings/dualbank/__init__.c
msgid "offset must be >= 0"
-msgstr ""
+msgstr "piān yí liàng bì xū >= 0"
+
+#: extmod/ulab/code/ulab_create.c
+msgid "offset must be non-negative and no greater than buffer length"
+msgstr "piān yí liàng bì xū wéi fēi fù shù qiě bù dà yú huǎn chōng qū cháng dù"
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
@@ -3408,7 +3453,7 @@ msgstr "cāozuò shǔ bùnéng yīqǐ guǎngbò"
#: extmod/ulab/code/ndarray.c
msgid "operation is implemented for 1D Boolean arrays only"
-msgstr ""
+msgstr "jǐn duì 1D bù ěr shù zǔ shí xiàn cāo zuò"
#: extmod/ulab/code/numerical/numerical.c
msgid "operation is not implemented on ndarrays"
@@ -3548,7 +3593,7 @@ msgstr "qǐngqiú chángdù %d dàn duìxiàng chángdù %d"
#: extmod/ulab/code/ndarray_operators.c
msgid "results cannot be cast to specified type"
-msgstr ""
+msgstr "wú fǎ jiāng jié guǒ qiáng zhì zhuǎn huàn dào zhǐ dìng lèi xíng"
#: py/compile.c
msgid "return annotation must be an identifier"
@@ -3570,7 +3615,7 @@ msgstr "rgb_pins[%d] yǔ shízhōng bùzài tóng yīgè duānkǒu shàng"
#: extmod/ulab/code/numerical/numerical.c
msgid "roll argument must be an ndarray"
-msgstr ""
+msgstr "gǔn dòng cān shù bì xū shì ndarray"
#: py/objstr.c
msgid "rsplit(None,n)"
@@ -3598,11 +3643,11 @@ msgstr "bù zhīchí jiǎoběn biānyì"
#: extmod/ulab/code/ndarray.c
msgid "shape must be a tuple"
-msgstr ""
+msgstr "xíng zhuàng bì xū shì yí gè yuán zǔ"
#: shared-module/msgpack/__init__.c
msgid "short read"
-msgstr ""
+msgstr "duǎn dú"
#: py/objstr.c
msgid "sign not allowed in string format specifier"
@@ -3735,7 +3780,7 @@ msgstr "Chāo shí shíjiān bìxū wèi 0.0 Dào 100.0 Miǎo"
#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "timeout must be < 655.35 secs"
-msgstr ""
+msgstr "chāo shí bì xū < 655.35 miǎo"
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "timeout must be >= 0.0"
@@ -3755,7 +3800,7 @@ msgstr "time_t shíjiān chuō chāochū píngtái fànwéi"
#: extmod/ulab/code/ndarray.c
msgid "tobytes can be invoked for dense arrays only"
-msgstr ""
+msgstr "tobytes zhǐ néng duì mì jí shù zǔ diào yòng"
#: shared-module/struct/__init__.c
msgid "too many arguments provided with the given format"
@@ -3763,7 +3808,7 @@ msgstr "tígōng jǐ dìng géshì de cānshù tài duō"
#: extmod/ulab/code/ulab_create.c
msgid "too many dimensions"
-msgstr ""
+msgstr "chǐ cùn tài duō"
#: extmod/ulab/code/ndarray.c
msgid "too many indices"
@@ -3776,7 +3821,7 @@ msgstr "dǎkāi tài duō zhí (yùqí %d)"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays"
-msgstr ""
+msgstr "wéi 1D shù zǔ dìng yì xiàn jǐng"
#: extmod/ulab/code/approx/approx.c
msgid "trapz is defined for 1D arrays of equal length"
@@ -3784,7 +3829,7 @@ msgstr "Trapz shì wèi děng zhǎng de 1D shùzǔ dìngyì de"
#: ports/esp32s2/common-hal/alarm/pin/__init__.c
msgid "trigger level must be 0 or 1"
-msgstr ""
+msgstr "chù fā jí bié bì xū wéi 0 huò 1"
#: py/obj.c
msgid "tuple/list has wrong length"
@@ -3926,7 +3971,7 @@ msgstr "xiàngliàng bìxū jùyǒu xiāngtóng de chángdù"
#: ports/esp32s2/common-hal/alarm/pin/__init__.c
msgid "wakeup conflict"
-msgstr ""
+msgstr "huàn xǐng chōng tū"
#: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c
msgid "watchdog not initialized"
@@ -3940,17 +3985,21 @@ msgstr "kān mén gǒu chāoshí bìxū dàyú 0"
msgid "width must be greater than zero"
msgstr "kuāndù bìxū dàyú líng"
+#: ports/esp32s2/common-hal/wifi/Radio.c
+msgid "wifi is not enabled"
+msgstr "wèi qǐ yòng WIFI"
+
#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "Chuāngkǒu bìxū shì <= jiàngé"
#: extmod/ulab/code/numerical/numerical.c
msgid "wrong axis index"
-msgstr ""
+msgstr "cuò wù de zhóu suǒ yǐn"
#: extmod/ulab/code/ulab_create.c
msgid "wrong axis specified"
-msgstr ""
+msgstr "zhǐ dìng de zhóu cuò wù"
#: extmod/ulab/code/vector/vectorise.c
msgid "wrong input type"
@@ -3978,7 +4027,7 @@ msgstr "x zhí chāochū biānjiè"
#: ports/esp32s2/common-hal/audiobusio/__init__.c
msgid "xTaskCreate failed"
-msgstr ""
+msgstr "xTaskCreate shī bài"
#: shared-bindings/displayio/Shape.c
msgid "y should be an int"
@@ -4004,6 +4053,9 @@ msgstr "zi bìxū wèi fú diǎn xíng"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)"
+#~ msgid "Unknown failure"
+#~ msgstr "Wèizhī gùzhàng"
+
#~ msgid "input argument must be an integer or a 2-tuple"
#~ msgstr "shūrù cānshù bìxū shì zhěngshù huò 2 yuán zǔ"
diff --git a/main.c b/main.c
index 91b6a062d..d9cdcca1d 100755
--- a/main.c
+++ b/main.c
@@ -317,7 +317,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
// Program has finished running.
- bool serial_connected_before_animation = serial_connected();
+ bool printed_press_any_key = false;
#if CIRCUITPY_DISPLAYIO
bool refreshed_epaper_display = false;
#endif
@@ -364,7 +364,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
}
#endif
- if (!serial_connected_before_animation && serial_connected()) {
+ if (!printed_press_any_key && serial_connected()) {
if (!serial_connected_at_start) {
print_code_py_status_message(safe_mode);
}
@@ -372,11 +372,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
print_safe_mode_message(safe_mode);
serial_write("\n");
serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.\n"));
+ printed_press_any_key = true;
}
- if (serial_connected_before_animation && !serial_connected()) {
+ if (!serial_connected()) {
serial_connected_at_start = false;
+ printed_press_any_key = false;
}
- serial_connected_before_animation = serial_connected();
// Refresh the ePaper display if we have one. That way it'll show an error message.
#if CIRCUITPY_DISPLAYIO
diff --git a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk
index b5a4bc735..f976dfe78 100644
--- a/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/8086_commander/mpconfigboard.mk
@@ -22,7 +22,6 @@ CIRCUITPY_GAMEPAD = 1
CIRCUITPY_BUSDEVICE = 1
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD
#FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ADXL34x
diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
index d31d1f54a..36d463697 100644
--- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.mk
@@ -10,3 +10,4 @@ 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 7eb83a123..20307fc05 100644
--- a/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/arduino_mkrzero/mpconfigboard.mk
@@ -11,3 +11,5 @@ LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
SUPEROPT_GC = 0
+SUPEROPT_VM = 0
+CFLAGS_INLINE_LIMIT = 40
diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk
index 178258b6c..2ace30fb5 100755
--- a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk
@@ -16,6 +16,7 @@ CIRCUITPY_COUNTIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_VECTORIO = 0
+CIRCUITPY_BUSDEVICE = 0
MICROPY_PY_ASYNC_AWAIT = 0
SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
index 505f5c145..0b150a5fb 100644
--- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk
@@ -22,7 +22,6 @@ SUPEROPT_GC = 0
CFLAGS_INLINE_LIMIT = 55
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
index c3be33134..ae0b6837c 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.mk
@@ -22,11 +22,10 @@ CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
SUPEROPT_GC = 0
-CFLAGS_INLINE_LIMIT = 50
+CFLAGS_INLINE_LIMIT = 40
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
index 4b0c324fa..1586a3289 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h
@@ -43,5 +43,3 @@
// USB is always used internally so skip the pin objects for it.
#define IGNORE_PIN_PA24 1
#define IGNORE_PIN_PA25 1
-
-#define MICROPY_PY_URE 0
diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
index 51e9b05af..aace5c0cb 100644
--- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk
@@ -18,6 +18,7 @@ CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CPERIPHERAL = 0
CIRCUITPY_MSGPACK = 0
CIRCUITPY_PIXELBUF = 0
+CIRCUITPY_RE = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
# So not all of displayio, sorry!
@@ -27,7 +28,6 @@ SUPEROPT_GC = 0
CFLAGS_INLINE_LIMIT = 55
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk
index 143910318..ab6c4ed99 100644
--- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_adalogger/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/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
index f06163b84..309563ff4 100644
--- a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk
@@ -21,7 +21,6 @@ CFLAGS_INLINE_LIMIT = 50
CIRCUITPY_MSGPACK = 0
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
index 6e089bb90..6ea21ed82 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.mk
@@ -28,5 +28,4 @@ CFLAGS_INLINE_LIMIT = 35
SUPEROPT_GC = 0
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69
diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
index 383b6a6df..76a6be2e3 100644
--- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.mk
@@ -29,5 +29,4 @@ CFLAGS_INLINE_LIMIT = 35
SUPEROPT_GC = 0
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM9x
diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
index 0345417a9..e1c0f4b9a 100644
--- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.mk
@@ -20,4 +20,5 @@ 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 1931ceb9a..2b211abd4 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
@@ -27,7 +27,6 @@ CFLAGS_INLINE_LIMIT = 55
SUPEROPT_GC = 0
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
index 98920b54f..792696763 100644
--- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
+++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h
@@ -12,7 +12,7 @@
// These are pins not to reset.
// QSPI Data pins
#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
-// DotStar pins, QSPI CS, and QSPI SCK
+// DotStar SCK, DotStar MOSI, QSPI SCK, and QSPI CS
#define MICROPY_PORT_B (PORT_PB02 | PORT_PB03 | PORT_PB10 | PORT_PB11)
#define MICROPY_PORT_C (0)
#define MICROPY_PORT_D (0)
diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
index 4895cda77..58d4e4980 100644
--- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk
@@ -10,3 +10,5 @@ QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 3
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
LONGINT_IMPL = MPZ
+
+CIRCUITPY__EVE = 1
diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk
index b7b8073ab..a82362b8d 100644
--- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk
@@ -21,7 +21,6 @@ CIRCUITPY_GAMEPAD = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_PS2IO = 0
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD
diff --git a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk
index f49bb3fef..3bf42d705 100644
--- a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk
@@ -21,7 +21,6 @@ CIRCUITPY_GAMEPAD = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_PS2IO = 0
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD
diff --git a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk
index 964cbe643..e100e2da6 100644
--- a/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/qtpy_m0/mpconfigboard.mk
@@ -11,14 +11,6 @@ LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
SUPEROPT_GC = 0
+SUPEROPT_VM = 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/sam32/mpconfigboard.mk b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
index 1dc686ef8..9ac24a014 100644
--- a/ports/atmel-samd/boards/sam32/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sam32/mpconfigboard.mk
@@ -13,5 +13,4 @@ LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_USTACK = 1
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
diff --git a/ports/atmel-samd/boards/serpente/mpconfigboard.mk b/ports/atmel-samd/boards/serpente/mpconfigboard.mk
index 6e953adf7..09036875f 100644
--- a/ports/atmel-samd/boards/serpente/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/serpente/mpconfigboard.mk
@@ -14,6 +14,7 @@ LONGINT_IMPL = NONE
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_GAMEPAD = 0
+CIRCUITPY_BUSDEVICE = 0
SUPEROPT_GC = 0
diff --git a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
index e71bb0739..2e15bc042 100755
--- a/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_lumidrive/mpconfigboard.mk
@@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_VECTORIO = 0
+CIRCUITPY_BUSDEVICE = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
diff --git a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
index a2bd577cd..3104be0a0 100644
--- a/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/sparkfun_samd21_dev/mpconfigboard.mk
@@ -10,4 +10,10 @@ 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
diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
index b1242d206..640d421e8 100644
--- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk
@@ -28,6 +28,7 @@ CIRCUITPY_RTC = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_USB_HID = 0
CIRCUITPY_USB_MIDI = 0
+CIRCUITPY_BUSDEVICE = 0
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame10
diff --git a/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk b/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk
index 3562228c7..d6f333b5b 100644
--- a/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/xinabox_cc03/mpconfigboard.mk
@@ -24,4 +24,3 @@ CIRCUITPY_TOUCHIO=0
CIRCUITPY_BUSDEVICE=1
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
diff --git a/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk b/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk
index 53908293f..fd2fa044a 100644
--- a/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/xinabox_cs11/mpconfigboard.mk
@@ -27,5 +27,4 @@ CIRCUITPY_COUNTIO=0
CIRCUITPY_BUSDEVICE=1
# Include these Python libraries in firmware.
-FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD
diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h
index bce89e0b9..d2a529485 100644
--- a/ports/atmel-samd/mpconfigport.h
+++ b/ports/atmel-samd/mpconfigport.h
@@ -45,11 +45,7 @@
#define MICROPY_PY_BUILTINS_COMPLEX (0)
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0)
#define MICROPY_PY_FUNCTION_ATTRS (0)
-// MICROPY_PY_UJSON depends on MICROPY_PY_IO
-#define MICROPY_PY_IO (0)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
-#define MICROPY_PY_UBINASCII (0)
-#define MICROPY_PY_UJSON (0)
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0)
#define MICROPY_PY_UERRNO_LIST \
X(EPERM) \
@@ -84,9 +80,6 @@
#define SPI_FLASH_MAX_BAUDRATE 24000000
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1)
#define MICROPY_PY_FUNCTION_ATTRS (1)
-// MICROPY_PY_UJSON depends on MICROPY_PY_IO
-#define MICROPY_PY_IO (1)
-#define MICROPY_PY_UJSON (1)
// MICROPY_PY_UERRNO_LIST - Use the default
#endif // SAM_D5X_E5X
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 17e3995bf..fb9cdf2e6 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -20,26 +20,16 @@ endif
# Put samd21-only choices here.
ifeq ($(CHIP_FAMILY),samd21)
-# frequencyio not yet verified as working on SAMD21, though make it possible to override.
-ifndef CIRCUITPY_AUDIOMIXER
-CIRCUITPY_AUDIOMIXER = 0
-endif
-
-ifndef CIRCUITPY_AUDIOMP3
-CIRCUITPY_AUDIOMP3 = 0
-endif
-
-ifndef CIRCUITPY_BUILTINS_POW3
-CIRCUITPY_BUILTINS_POW3 = 0
-endif
-ifndef CIRCUITPY_FREQUENCYIO
-CIRCUITPY_FREQUENCYIO = 0
-endif
+# The ?='s allow overriding in mpconfigboard.mk.
-ifndef CIRCUITPY_TOUCHIO_USE_NATIVE
-CIRCUITPY_TOUCHIO_USE_NATIVE = 1
-endif
+CIRCUITPY_AUDIOMIXER ?= 0
+CIRCUITPY_BINASCII ?= 0
+CIRCUITPY_AUDIOMP3 ?= 0
+CIRCUITPY_BUILTINS_POW3 ?= 0
+CIRCUITPY_FREQUENCYIO ?= 0
+CIRCUITPY_JSON ?= 0
+CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1
# No room for HCI _bleio on SAMD21.
CIRCUITPY_BLEIO_HCI = 0
@@ -71,27 +61,13 @@ ifeq ($(CHIP_FAMILY),samd51)
# No native touchio on SAMD51.
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
-# The ifndef's allow overriding in mpconfigboard.mk.
-
-ifndef CIRCUITPY_NETWORK
-CIRCUITPY_NETWORK = 0
-endif
-
-ifndef CIRCUITPY_PS2IO
-CIRCUITPY_PS2IO = 1
-endif
-
-ifndef CIRCUITPY_SAMD
-CIRCUITPY_SAMD = 1
-endif
-
-ifndef CIRCUITPY_RGBMATRIX
-CIRCUITPY_RGBMATRIX = $(CIRCUITPY_FULL_BUILD)
-endif
+# The ?='s allow overriding in mpconfigboard.mk.
-ifndef CIRCUITPY_FRAMEBUFFERIO
-CIRCUITPY_FRAMEBUFFERIO = $(CIRCUITPY_FULL_BUILD)
-endif
+CIRCUITPY_NETWORK ?= 0
+CIRCUITPY_PS2IO ?= 1
+CIRCUITPY_SAMD ?= 1
+CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD)
+CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD)
endif # samd51
diff --git a/ports/cxd56/README.md b/ports/cxd56/README.md
index 7fa439aac..c399b8a4d 100644
--- a/ports/cxd56/README.md
+++ b/ports/cxd56/README.md
@@ -75,7 +75,7 @@ Bootloader information:
* You have to accept the End User License Agreement to be able to download and use the Spresense bootloader binary.
-Download the spresense binaries zip archive from: [Spresense firmware v2-0-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-0-000)
+Download the spresense binaries zip archive from: [Spresense firmware v2-0-002](https://developer.sony.com/file/download/download-spresense-firmware-v2-0-002)
Extract spresense binaries in your PC to ports/spresense/spresense-exported-sdk/firmware/
diff --git a/ports/cxd56/configs/circuitpython/defconfig b/ports/cxd56/configs/circuitpython/defconfig
index a97f821df..096b53b80 100644
--- a/ports/cxd56/configs/circuitpython/defconfig
+++ b/ports/cxd56/configs/circuitpython/defconfig
@@ -165,6 +165,7 @@ CONFIG_USBDEV=y
CONFIG_USBDEV_DMA=y
CONFIG_USBDEV_DUALSPEED=y
CONFIG_USEC_PER_TICK=1000
+CONFIG_USERMAIN_STACKSIZE=8192
CONFIG_USER_ENTRYPOINT="spresense_main"
CONFIG_VIDEO_ISX012=y
CONFIG_VIDEO_STREAM=y
diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk
-Subproject 752c4cd56dd0a270a559c28272ceb61ddcb7806
+Subproject 2ec2a1538362696118dc3fdf56f33dacaf8f406
diff --git a/ports/cxd56/supervisor/internal_flash.c b/ports/cxd56/supervisor/internal_flash.c
index 2726fa4a2..9c103fb19 100644
--- a/ports/cxd56/supervisor/internal_flash.c
+++ b/ports/cxd56/supervisor/internal_flash.c
@@ -30,10 +30,10 @@
/* Prototypes for Remote API */
-int FM_RawWrite(uint32_t offset, const void *buf, uint32_t size);
-int FM_RawVerifyWrite(uint32_t offset, const void *buf, uint32_t size);
-int FM_RawRead(uint32_t offset, void *buf, uint32_t size);
-int FM_RawEraseSector(uint32_t sector);
+int fw_fm_rawwrite(uint32_t offset, const void *buf, uint32_t size);
+int fw_fm_rawverifywrite(uint32_t offset, const void *buf, uint32_t size);
+int fw_fm_rawread(uint32_t offset, void *buf, uint32_t size);
+int fw_fm_rawerasesector(uint32_t sector);
#define CXD56_SPIFLASHSIZE (16 * 1024 * 1024)
@@ -64,8 +64,8 @@ void port_internal_flash_flush(void) {
return;
}
- FM_RawEraseSector(flash_sector);
- FM_RawWrite(flash_sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE);
+ fw_fm_rawerasesector(flash_sector);
+ fw_fm_rawwrite(flash_sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE);
flash_sector = NO_SECTOR;
}
@@ -73,7 +73,7 @@ void port_internal_flash_flush(void) {
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
supervisor_flash_flush();
- if (FM_RawRead(block << PAGE_SHIFT, dest, num_blocks << PAGE_SHIFT) < 0) {
+ if (fw_fm_rawread(block << PAGE_SHIFT, dest, num_blocks << PAGE_SHIFT) < 0) {
return 1;
}
@@ -92,7 +92,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
if (sector != flash_sector) {
supervisor_flash_flush();
- if (FM_RawRead(sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE) < 0) {
+ if (fw_fm_rawread(sector << SECTOR_SHIFT, flash_cache, SECTOR_SIZE) < 0) {
return 1;
}
diff --git a/ports/esp32s2/common-hal/displayio/ParallelBus.c b/ports/esp32s2/common-hal/displayio/ParallelBus.c
index d0c98f361..f77b37b57 100644
--- a/ports/esp32s2/common-hal/displayio/ParallelBus.c
+++ b/ports/esp32s2/common-hal/displayio/ParallelBus.c
@@ -33,35 +33,196 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/microcontroller/__init__.h"
+/*
+ * Current pin limitations for ESP32-S2 ParallelBus:
+ * - data0 pin must be byte aligned
+ */
+
void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self,
const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select,
const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) {
- mp_raise_NotImplementedError(translate("ParallelBus not yet supported"));
+ uint8_t data_pin = data0->number;
+ if (data_pin % 8 != 0) {
+ mp_raise_ValueError(translate("Data 0 pin must be byte aligned."));
+ }
+
+ for (uint8_t i = 0; i < 8; i++) {
+ if (!pin_number_is_free(data_pin + i)) {
+ mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i);
+ }
+ }
+
+ gpio_dev_t *g = &GPIO; // this is the GPIO registers, see "extern gpio_dev_t GPIO" from file:gpio_struct.h
+
+ // Setup the pins as "Simple GPIO outputs" see section 19.3.3 of the ESP32-S2 Reference Manual
+ // Enable pins with "enable_w1ts"
+
+ for (uint8_t i = 0; i < 8; i++) {
+ g->enable_w1ts = (0x1 << (data_pin + i));
+ g->func_out_sel_cfg[data_pin + i].val= 256; /* setup output pin for simple GPIO Output, (0x100 = 256) */
+
+ }
+
+ /* From my understanding, there is a limitation of the ESP32-S2 that does not allow single-byte writes
+ * into the GPIO registers. See section 10.3.3 regarding "non-aligned writes" into the registers.
+ */
+
+
+ if (data_pin < 31) {
+ self->bus = (uint32_t*) &g->out; //pointer to GPIO output register (for pins 0-31)
+ } else {
+ self->bus = (uint32_t*) &g->out1.val; //pointer to GPIO output register (for pins >= 32)
+ }
+
+ /* SNIP - common setup of command, chip select, write and read pins, same as from SAMD and NRF ports */
+ self->command.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->command, command);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL);
+
+ self->chip_select.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL);
+
+ self->write.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->write, write);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL);
+
+ self->read.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->read, read);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL);
+
+ self->data0_pin = data_pin;
+
+ if (write->number < 32) {
+ self->write_clear_register = (uint32_t*) &g->out_w1tc;
+ self->write_set_register = (uint32_t*) &g->out_w1ts;
+ } else {
+ self->write_clear_register = (uint32_t*) &g->out1_w1tc.val;
+ self->write_set_register = (uint32_t*) &g->out1_w1ts.val;
+ }
+
+ // Check to see if the data and write pins are on the same register:
+ if ( ( ((self->data0_pin < 32) && (write->number < 32)) ) ||
+ ( ((self->data0_pin > 31) && (write->number > 31)) ) ) {
+ self->data_write_same_register = true; // data pins and write pin are on the same register
+ } else {
+ self->data_write_same_register = false; // data pins and write pins are on different registers
+ }
+
+
+ self->write_mask = 1 << (write->number % 32); /* the write pin triggers the LCD to latch the data */
+
+ /* SNIP - common setup of the reset pin, same as from SAMD and NRF ports */
+ self->reset.base.type = &mp_type_NoneType;
+ if (reset != NULL) {
+ self->reset.base.type = &digitalio_digitalinout_type;
+ common_hal_digitalio_digitalinout_construct(&self->reset, reset);
+ common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
+ never_reset_pin_number(reset->number);
+ common_hal_displayio_parallelbus_reset(self);
+ }
+
+ never_reset_pin_number(command->number);
+ never_reset_pin_number(chip_select->number);
+ never_reset_pin_number(write->number);
+ never_reset_pin_number(read->number);
+ for (uint8_t i = 0; i < 8; i++) {
+ never_reset_pin_number(data_pin + i);
+ }
+
}
void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) {
+ /* SNIP - same as from SAMD and NRF ports */
+ for (uint8_t i = 0; i < 8; i++) {
+ reset_pin_number(self->data0_pin + i);
+ }
+ reset_pin_number(self->command.pin->number);
+ reset_pin_number(self->chip_select.pin->number);
+ reset_pin_number(self->write.pin->number);
+ reset_pin_number(self->read.pin->number);
+ reset_pin_number(self->reset.pin->number);
}
bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
- return false;
+ /* SNIP - same as from SAMD and NRF ports */
+ displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
+ if (self->reset.base.type == &mp_type_NoneType) {
+ return false;
+ }
+
+ common_hal_digitalio_digitalinout_set_value(&self->reset, false);
+ common_hal_mcu_delay_us(4);
+ common_hal_digitalio_digitalinout_set_value(&self->reset, true);
+ return true;
+
}
bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
- return false;
+ /* SNIP - same as from SAMD and NRF ports */
+ return true;
}
bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
-
- return false;
+ /* SNIP - same as from SAMD and NRF ports */
+ displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
+ common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
+ return true;
}
void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type,
- display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) {
+ display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) {
+ displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
+ common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA);
+
+ uint32_t* clear_write = self->write_clear_register;
+ uint32_t* set_write = self->write_set_register;
+
+ const uint32_t mask = self->write_mask;
+
+ /* Setup structures for data writing. The ESP32-S2 port differs from the SAMD and NRF ports
+ * because I have not found a way to write a single byte into the ESP32-S2 registers.
+ * For the ESP32-S2, I create a 32-bit data_buffer that is used to transfer the data bytes.
+ */
+
+ *clear_write = mask; // Clear the write pin to prepare the registers before storing the
+ // register value into data_buffer
+
+ const uint32_t data_buffer = *self->bus; // store the initial output register values into the data output buffer
+ uint8_t* data_address = ((uint8_t*) &data_buffer) + (self->data0_pin / 8); /* address inside data_buffer where
+ * each data byte will be written to the data pin registers
+ */
+
+
+ if ( self->data_write_same_register ) { // data and write pins are on the same register
+ for (uint32_t i = 0; i < data_length; i++) {
+
+ /* Note: If the write pin and data pins are controlled by the same GPIO register, we can eliminate
+ * the "clear_write" step below, since the write pin is cleared when the data_buffer is written
+ * to the bus.
+ */
+
+ *(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location
+ *self->bus = data_buffer; // write the data to the output register
+ *set_write = mask; // set the write pin
+ }
+ }
+ else { // data and write pins are on different registers
+ for (uint32_t i = 0; i < data_length; i++) {
+ *clear_write = mask; // clear the write pin (See comment above, this may not be necessary).
+ *(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location
+ *self->bus = data_buffer; // write the data to the output register
+ *set_write = mask; // set the write pin
+
+ }
+ }
}
void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) {
-
+ /* SNIP - same as from SAMD and NRF ports */
+ displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
+ common_hal_digitalio_digitalinout_set_value(&self->chip_select, true);
}
diff --git a/ports/esp32s2/common-hal/displayio/ParallelBus.h b/ports/esp32s2/common-hal/displayio/ParallelBus.h
index cd636921d..84302118b 100644
--- a/ports/esp32s2/common-hal/displayio/ParallelBus.h
+++ b/ports/esp32s2/common-hal/displayio/ParallelBus.h
@@ -31,6 +31,17 @@
typedef struct {
mp_obj_base_t base;
+ uint32_t* bus; // pointer where 8 bits of data are written to the display
+ digitalio_digitalinout_obj_t command;
+ digitalio_digitalinout_obj_t chip_select;
+ digitalio_digitalinout_obj_t reset;
+ digitalio_digitalinout_obj_t write;
+ digitalio_digitalinout_obj_t read;
+ uint8_t data0_pin; // pin number for the lowest number data pin. Must be 8-bit aligned
+ bool data_write_same_register; // if data and write pins are in the sare
+ uint32_t* write_set_register; // pointer to the write group for setting the write bit to latch the data on the LCD
+ uint32_t* write_clear_register; // pointer to the write group for clearing the write bit to latch the data on the LCD
+ uint32_t write_mask; // bit mask for the single bit for the write pin register
} displayio_parallelbus_obj_t;
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
diff --git a/ports/esp32s2/common-hal/socketpool/Socket.c b/ports/esp32s2/common-hal/socketpool/Socket.c
index 5e943f8fd..69ef41c6e 100644
--- a/ports/esp32s2/common-hal/socketpool/Socket.c
+++ b/ports/esp32s2/common-hal/socketpool/Socket.c
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2020 Lucian Copeland 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
@@ -37,25 +38,162 @@
#include "components/lwip/lwip/src/include/lwip/sys.h"
#include "components/lwip/lwip/src/include/lwip/netdb.h"
+STATIC socketpool_socket_obj_t * open_socket_handles[CONFIG_LWIP_MAX_SOCKETS]; // 4 on the wrover/wroom
+
+void socket_reset(void) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) {
+ if (open_socket_handles[i]) {
+ if (open_socket_handles[i]->num > 0) {
+ common_hal_socketpool_socket_close(open_socket_handles[i]);
+ open_socket_handles[i] = NULL;
+ } else {
+ // accidentally got a TCP socket in here, or something.
+ open_socket_handles[i] = NULL;
+ }
+ }
+ }
+}
+
+bool register_open_socket(socketpool_socket_obj_t* self) {
+ for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) {
+ if (open_socket_handles[i] == NULL) {
+ open_socket_handles[i] = self;
+ return true;
+ }
+ }
+ return false;
+}
+
+STATIC void _lazy_init_LWIP(socketpool_socket_obj_t* self) {
+ if (self->num != -1) {
+ return; //safe to call on existing socket
+ }
+ if (self->tls != NULL) {
+ mp_raise_RuntimeError(translate("Invalid use of TLS Socket"));
+ }
+ int socknum = -1;
+ socknum = lwip_socket(self->family, self->type, self->ipproto);
+ if (socknum < 0 || !register_open_socket(self)) {
+ mp_raise_RuntimeError(translate("Out of sockets"));
+ }
+ self->num = socknum;
+ lwip_fcntl(socknum, F_SETFL, O_NONBLOCK);
+}
+
+STATIC void _lazy_init_TLS(socketpool_socket_obj_t* self) {
+ if (self->type != SOCK_STREAM || self->num != -1) {
+ mp_raise_RuntimeError(translate("Invalid socket for TLS"));
+ }
+ esp_tls_t* tls_handle = esp_tls_init();
+ if (tls_handle == NULL) {
+ mp_raise_espidf_MemoryError();
+ }
+ self->tls = tls_handle;
+}
+
void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms) {
self->timeout_ms = timeout_ms;
}
-bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, mp_uint_t hostlen, mp_int_t port) {
+bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self,
+ const char* host, size_t hostlen, uint8_t port) {
+ _lazy_init_LWIP(self);
+
+ struct sockaddr_in bind_addr;
+ bind_addr.sin_addr.s_addr = inet_addr(host);
+ bind_addr.sin_family = AF_INET;
+ bind_addr.sin_port = htons(port);
+
+ int opt = 1;
+ int err = lwip_setsockopt(self->num, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ if (err != 0) {
+ mp_raise_RuntimeError(translate("Issue setting SO_REUSEADDR"));
+ }
+ int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == 0;
+ return result;
+}
+
+bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t* self, int backlog) {
+ return lwip_listen(self->num, backlog) == 0;
+}
+
+socketpool_socket_obj_t* common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self,
+ uint8_t* ip, uint *port) {
+ struct sockaddr_in accept_addr;
+ socklen_t socklen = sizeof(accept_addr);
+ int newsoc = -1;
+ bool timed_out = false;
+ uint64_t start_ticks = supervisor_ticks_ms64();
+
+ if (self->timeout_ms != (uint)-1) {
+ mp_printf(&mp_plat_print, "will timeout");
+ } else {
+ mp_printf(&mp_plat_print, "won't timeout");
+ }
+
+ // Allow timeouts and interrupts
+ while (newsoc == -1 &&
+ !timed_out &&
+ !mp_hal_is_interrupted()) {
+ if (self->timeout_ms != (uint)-1) {
+ timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
+ }
+ RUN_BACKGROUND_TASKS;
+ newsoc = lwip_accept(self->num, (struct sockaddr *)&accept_addr, &socklen);
+ // In non-blocking mode, fail instead of looping
+ if (newsoc == -1 && self->timeout_ms == 0) {
+ mp_raise_OSError(MP_EAGAIN);
+ }
+ }
+
+ if (!timed_out) {
+ // harmless on failure but avoiding memcpy is faster
+ memcpy((void *)ip, (void*)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr));
+ *port = accept_addr.sin_port;
+ } else {
+ mp_raise_OSError(ETIMEDOUT);
+ }
+
+ if (newsoc > 0) {
+ // Create the socket
+ socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
+ sock->base.type = &socketpool_socket_type;
+ sock->num = newsoc;
+ sock->tls = NULL;
+ sock->ssl_context = NULL;
+ sock->pool = self->pool;
+
+ if (!register_open_socket(sock)) {
+ mp_raise_OSError(MP_EBADF);
+ }
+
+ lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK);
+ return sock;
+ } else {
+ mp_raise_OSError(MP_EBADF);
+ return NULL;
+ }
+}
+
+bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self,
+ const char* host, mp_uint_t hostlen, mp_int_t port) {
// For simplicity we use esp_tls for all TCP connections. If it's not SSL, ssl_context will be
// NULL and should still work. This makes regular TCP connections more memory expensive but TLS
// should become more and more common. Therefore, we optimize for the TLS case.
+ // Todo: move to SSL Wrapper and add lwip_connect()
+ _lazy_init_TLS(self);
+
esp_tls_cfg_t* tls_config = NULL;
if (self->ssl_context != NULL) {
tls_config = &self->ssl_context->ssl_config;
}
- int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tcp);
+ int result = esp_tls_conn_new_sync(host, hostlen, port, tls_config, self->tls);
self->connected = result >= 0;
if (result < 0) {
int esp_tls_code;
int flags;
- esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags);
+ esp_err_t err = esp_tls_get_and_clear_last_error(self->tls->error_handle, &esp_tls_code, &flags);
if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) {
mp_raise_espidf_MemoryError();
@@ -70,7 +208,7 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c
// shouldn't hit this timeout because we try to only read available data. However, there is
// always a chance that we try to read something that is used internally.
int fd;
- esp_tls_get_conn_sockfd(self->tcp, &fd);
+ esp_tls_get_conn_sockfd(self->tls, &fd);
struct timeval tv;
tv.tv_sec = 2 * 60; // Two minutes
tv.tv_usec = 0;
@@ -86,7 +224,15 @@ bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t* self) {
}
mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) {
- size_t sent = esp_tls_conn_write(self->tcp, buf, len);
+ int sent = -1;
+ if (self->num != -1) {
+ // LWIP Socket
+ // TODO: deal with potential failure/add timeout?
+ sent = lwip_send(self->num, buf, len, 0);
+ } else if (self->tls != NULL) {
+ // TLS Socket
+ sent = esp_tls_conn_write(self->tls, buf, len);
+ }
if (sent < 0) {
mp_raise_OSError(MP_ENOTCONN);
@@ -95,45 +241,73 @@ mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t* self, const
}
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len) {
- size_t received = 0;
- int status = 0;
- uint64_t start_ticks = supervisor_ticks_ms64();
- int sockfd;
- esp_err_t err = esp_tls_get_conn_sockfd(self->tcp, &sockfd);
- if (err != ESP_OK) {
- mp_raise_OSError(MP_EBADF);
- }
- while (received == 0 &&
- status >= 0 &&
- (self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) &&
- !mp_hal_is_interrupted()) {
- RUN_BACKGROUND_TASKS;
- size_t available = esp_tls_get_bytes_avail(self->tcp);
- if (available == 0) {
- // This reads the raw socket buffer and is used for non-TLS connections
- // and between encrypted TLS blocks.
- status = lwip_ioctl(sockfd, FIONREAD, &available);
+ int received = 0;
+ bool timed_out = false;
+
+ if (self->num != -1) {
+ // LWIP Socket
+ uint64_t start_ticks = supervisor_ticks_ms64();
+ received = -1;
+ while (received == -1 &&
+ !timed_out &&
+ !mp_hal_is_interrupted()) {
+ if (self->timeout_ms != (uint)-1) {
+ timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
+ }
+ RUN_BACKGROUND_TASKS;
+ received = lwip_recv(self->num, (void*) buf, len - 1, 0);
+
+ // In non-blocking mode, fail instead of looping
+ if (received == -1 && self->timeout_ms == 0) {
+ mp_raise_OSError(MP_EAGAIN);
+ }
}
- size_t remaining = len - received;
- if (available > remaining) {
- available = remaining;
+ } else if (self->tls != NULL) {
+ // TLS Socket
+ int status = 0;
+ uint64_t start_ticks = supervisor_ticks_ms64();
+ int sockfd;
+ esp_err_t err = esp_tls_get_conn_sockfd(self->tls, &sockfd);
+ if (err != ESP_OK) {
+ mp_raise_OSError(MP_EBADF);
}
- if (available > 0) {
- status = esp_tls_conn_read(self->tcp, (void*) buf + received, available);
- if (status == 0) {
- // Reading zero when something is available indicates a closed
- // connection. (The available bytes could have been TLS internal.)
- break;
+ while (received == 0 &&
+ status >= 0 &&
+ !timed_out &&
+ !mp_hal_is_interrupted()) {
+ if (self->timeout_ms != (uint)-1) {
+ timed_out = self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
+ }
+ RUN_BACKGROUND_TASKS;
+ size_t available = esp_tls_get_bytes_avail(self->tls);
+ if (available == 0) {
+ // This reads the raw socket buffer and is used for non-TLS connections
+ // and between encrypted TLS blocks.
+ status = lwip_ioctl(sockfd, FIONREAD, &available);
}
- if (status > 0) {
- received += status;
+ size_t remaining = len - received;
+ if (available > remaining) {
+ available = remaining;
+ }
+ if (available > 0) {
+ status = esp_tls_conn_read(self->tls, (void*) buf + received, available);
+ if (status == 0) {
+ // Reading zero when something is available indicates a closed
+ // connection. (The available bytes could have been TLS internal.)
+ break;
+ }
+ if (status > 0) {
+ received += status;
+ }
}
}
+ } else {
+ // Socket does not have a valid descriptor of either type
+ mp_raise_OSError(MP_EBADF);
}
- if (received == 0) {
- // socket closed
- common_hal_socketpool_socket_close(self);
+ if (timed_out) {
+ mp_raise_OSError(ETIMEDOUT);
}
return received;
}
@@ -141,6 +315,8 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self,
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) {
+ _lazy_init_LWIP(self);
+
// Get the IP address string
const struct addrinfo hints = {
.ai_family = AF_INET,
@@ -151,17 +327,15 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self,
if (error != 0 || result == NULL) {
return 0;
}
+
+ // Set parameters
+ struct sockaddr_in dest_addr;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
- struct in_addr *addr = &((struct sockaddr_in *)result->ai_addr)->sin_addr;
+ dest_addr.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
#pragma GCC diagnostic pop
- char ip_str[IP4ADDR_STRLEN_MAX];
- inet_ntoa_r(*addr, ip_str, IP4ADDR_STRLEN_MAX);
freeaddrinfo(result);
- // Set parameters
- struct sockaddr_in dest_addr;
- dest_addr.sin_addr.s_addr = inet_addr((const char *)ip_str);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(port);
@@ -176,26 +350,50 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t* self,
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) {
+ _lazy_init_LWIP(self);
+
struct sockaddr_in source_addr;
socklen_t socklen = sizeof(source_addr);
- 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;
+ // LWIP Socket
+ uint64_t start_ticks = supervisor_ticks_ms64();
+ int received = -1;
+ bool timed_out = false;
+ while (received == -1 &&
+ !timed_out &&
+ !mp_hal_is_interrupted()) {
+ if (self->timeout_ms != (uint)-1) {
+ timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
+ }
+ RUN_BACKGROUND_TASKS;
+ received = lwip_recvfrom(self->num, buf, len, 0, (struct sockaddr *)&source_addr, &socklen);
+
+ // In non-blocking mode, fail instead of looping
+ if (received == -1 && self->timeout_ms == 0) {
+ mp_raise_OSError(MP_EAGAIN);
+ }
+ }
- if (bytes_received < 0) {
+ if (!timed_out) {
+ memcpy((void *)ip, (void*)&source_addr.sin_addr.s_addr, sizeof(source_addr.sin_addr.s_addr));
+ *port = source_addr.sin_port;
+ } else {
+ mp_raise_OSError(ETIMEDOUT);
+ }
+
+ if (received < 0) {
mp_raise_BrokenPipeError();
return 0;
}
- return bytes_received;
+ return received;
}
void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) {
self->connected = false;
- if (self->tcp != NULL) {
- esp_tls_conn_destroy(self->tcp);
- self->tcp = NULL;
+ if (self->tls != NULL) {
+ esp_tls_conn_destroy(self->tls);
+ self->tls = NULL;
}
if (self->num >= 0) {
lwip_shutdown(self->num, 0);
@@ -205,7 +403,7 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t* self) {
}
bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t* self) {
- return self->tcp == NULL && self->num < 0;
+ return self->tls == NULL && self->num < 0;
}
diff --git a/ports/esp32s2/common-hal/socketpool/Socket.h b/ports/esp32s2/common-hal/socketpool/Socket.h
index 62b5ded58..4e6cfa5ef 100644
--- a/ports/esp32s2/common-hal/socketpool/Socket.h
+++ b/ports/esp32s2/common-hal/socketpool/Socket.h
@@ -37,11 +37,17 @@
typedef struct {
mp_obj_base_t base;
int num;
+ int type;
+ int family;
+ int ipproto;
bool connected;
- esp_tls_t* tcp;
+ esp_tls_t* tls;
ssl_sslcontext_obj_t* ssl_context;
socketpool_socketpool_obj_t* pool;
mp_uint_t timeout_ms;
} socketpool_socket_obj_t;
+void socket_reset(void);
+bool register_open_socket(socketpool_socket_obj_t* self);
+
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SOCKETPOOL_SOCKET_H
diff --git a/ports/esp32s2/common-hal/socketpool/SocketPool.c b/ports/esp32s2/common-hal/socketpool/SocketPool.c
index 3bec5f337..5821728ce 100644
--- a/ports/esp32s2/common-hal/socketpool/SocketPool.c
+++ b/ports/esp32s2/common-hal/socketpool/SocketPool.c
@@ -65,25 +65,20 @@ socketpool_socket_obj_t* common_hal_socketpool_socket(socketpool_socketpool_obj_
mp_raise_NotImplementedError(translate("Only IPv4 sockets supported"));
}
- int socknum = -1;
- esp_tls_t* tcp_handle = NULL;
- if (socket_type == SOCK_DGRAM || socket_type == SOCK_RAW) {
- socknum = lwip_socket(addr_family, socket_type, ipproto);
- } else {
- tcp_handle = esp_tls_init();
-
- if (tcp_handle == NULL) {
- mp_raise_espidf_MemoryError();
- }
- }
- if (socknum < 0 && tcp_handle == NULL) {
- mp_raise_RuntimeError(translate("Out of sockets"));
- }
-
+ // Consider LWIP and MbedTLS "variant" sockets to be incompatible (for now)
+ // The variant of the socket is determined by whether the socket is wrapped
+ // by SSL. If no TLS handle is set in sslcontext_wrap_socket, the first call
+ // of bind() or connect() will create a LWIP socket with a corresponding
+ // socketnum.
+ // TODO: move MbedTLS to its own duplicate Socket or Server API, maybe?
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
sock->base.type = &socketpool_socket_type;
- sock->num = socknum;
- sock->tcp = tcp_handle;
+ sock->num = -1;
+ sock->type = socket_type;
+ sock->family = addr_family;
+ sock->ipproto = ipproto;
+
+ sock->tls = NULL;
sock->ssl_context = NULL;
sock->pool = self;
return sock;
diff --git a/ports/esp32s2/common-hal/wifi/Radio.c b/ports/esp32s2/common-hal/wifi/Radio.c
index 930230088..574bab0a1 100644
--- a/ports/esp32s2/common-hal/wifi/Radio.c
+++ b/ports/esp32s2/common-hal/wifi/Radio.c
@@ -72,7 +72,7 @@ void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) {
}
if (!self->started && enabled) {
// esp_wifi_start() would default to soft-AP, thus setting it to station
- ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+ start_station(self);
ESP_ERROR_CHECK(esp_wifi_start());
self->started = true;
return;
@@ -89,7 +89,9 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
if (self->current_scan != NULL) {
mp_raise_RuntimeError(translate("Already scanning for wifi networks"));
}
- // check enabled
+ if (!common_hal_wifi_radio_get_enabled(self)) {
+ mp_raise_RuntimeError(translate("wifi is not enabled"));
+ }
start_station(self);
wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t);
@@ -126,7 +128,25 @@ void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *host
}
wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t* bssid, size_t bssid_len) {
- // check enabled
+ if (!common_hal_wifi_radio_get_enabled(self)) {
+ mp_raise_RuntimeError(translate("wifi is not enabled"));
+ }
+
+ EventBits_t bits;
+ // can't block since both bits are false after wifi_init
+ // both bits are true after an existing connection stops
+ bits = xEventGroupWaitBits(self->event_group_handle,
+ WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT,
+ pdTRUE,
+ pdTRUE,
+ 0);
+ if (((bits & WIFI_CONNECTED_BIT) != 0) &&
+ !((bits & WIFI_DISCONNECTED_BIT) != 0)) {
+ return WIFI_RADIO_ERROR_NONE;
+ }
+ // explicitly clear bits since xEventGroupWaitBits may have timed out
+ xEventGroupClearBits(self->event_group_handle, WIFI_CONNECTED_BIT);
+ xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT);
start_station(self);
wifi_config_t* config = &self->sta_config;
@@ -157,7 +177,6 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
self->retries_left = 5;
esp_wifi_connect();
- EventBits_t bits;
do {
RUN_BACKGROUND_TASKS;
bits = xEventGroupWaitBits(self->event_group_handle,
diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h
index 9c0fd9da3..0cf695bc9 100644
--- a/ports/esp32s2/mpconfigport.h
+++ b/ports/esp32s2/mpconfigport.h
@@ -30,7 +30,6 @@
#define MICROPY_NLR_THUMB (0)
-#define MICROPY_PY_UJSON (1)
#define MICROPY_USE_INTERNAL_PRINTF (0)
#define MICROPY_PY_SYS_PLATFORM "Espressif ESP32-S2"
diff --git a/ports/esp32s2/peripherals/touch.c b/ports/esp32s2/peripherals/touch.c
index 6cf33b2bd..cd895b10b 100644
--- a/ports/esp32s2/peripherals/touch.c
+++ b/ports/esp32s2/peripherals/touch.c
@@ -46,8 +46,13 @@ void peripherals_touch_init(const touch_pad_t touchpad) {
if (!touch_inited) {
touch_pad_init();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
+ }
+ // touch_pad_config() must be done before touch_pad_fsm_start() the first time.
+ // Otherwise the calibration is wrong and we get maximum raw values if there is
+ // a trace of any significant length on the pin.
+ touch_pad_config(touchpad);
+ if (!touch_inited) {
touch_pad_fsm_start();
touch_inited = true;
}
- touch_pad_config(touchpad);
}
diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c
index 6491e7430..534f7f71b 100644
--- a/ports/esp32s2/supervisor/port.c
+++ b/ports/esp32s2/supervisor/port.c
@@ -46,6 +46,7 @@
#include "common-hal/pulseio/PulseIn.h"
#include "common-hal/pwmio/PWMOut.h"
#include "common-hal/watchdog/WatchDogTimer.h"
+#include "common-hal/socketpool/Socket.h"
#include "common-hal/wifi/__init__.h"
#include "supervisor/memory.h"
#include "supervisor/shared/tick.h"
@@ -143,9 +144,9 @@ safe_mode_t port_init(void) {
case ESP_RST_BROWNOUT:
return BROWNOUT;
case ESP_RST_PANIC:
+ return HARD_CRASH;
case ESP_RST_INT_WDT:
case ESP_RST_WDT:
- return HARD_CRASH;
default:
break;
}
@@ -222,6 +223,10 @@ void reset_port(void) {
#if CIRCUITPY_WIFI
wifi_reset();
#endif
+
+#if CIRCUITPY_SOCKETPOOL
+ socket_reset();
+#endif
}
void reset_to_bootloader(void) {
diff --git a/ports/litex/mpconfigport.h b/ports/litex/mpconfigport.h
index a7caf8526..5f739e49e 100644
--- a/ports/litex/mpconfigport.h
+++ b/ports/litex/mpconfigport.h
@@ -31,8 +31,6 @@
#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
#define MICROPY_NLR_THUMB (0)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
-#define MICROPY_PY_UBINASCII (1)
-#define MICROPY_PY_UJSON (1)
#include "py/circuitpy_mpconfig.h"
diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h
index 7496256d0..51e0ef9ff 100644
--- a/ports/mimxrt10xx/mpconfigport.h
+++ b/ports/mimxrt10xx/mpconfigport.h
@@ -41,8 +41,6 @@ extern uint8_t _ld_default_stack_size;
#define CIRCUITPY_DEFAULT_STACK_SIZE ((uint32_t) &_ld_default_stack_size)
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0)
#define MICROPY_PY_FUNCTION_ATTRS (0)
-#define MICROPY_PY_IO (1)
-#define MICROPY_PY_UJSON (1)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk
index 76d15e608..c8cba2877 100644
--- a/ports/nrf/boards/pca10100/mpconfigboard.mk
+++ b/ports/nrf/boards/pca10100/mpconfigboard.mk
@@ -25,6 +25,7 @@ CIRCUITPY_RTC = 1
CIRCUITPY_SDCARDIO = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_ULAB = 0
+CIRCUITPY_BUSDEVICE = 0
MICROPY_PY_ASYNC_AWAIT = 0
SUPEROPT_GC = 0
diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk
index 4eb6c98c7..032caac40 100644
--- a/ports/nrf/boards/simmel/mpconfigboard.mk
+++ b/ports/nrf/boards/simmel/mpconfigboard.mk
@@ -13,11 +13,13 @@ INTERNAL_FLASH_FILESYSTEM = 1
CIRCUITPY_AESIO = 1
CIRCUITPY_AUDIOMP3 = 0
+CIRCUITPY_BUSDEVICE = 0
CIRCUITPY_BUSIO = 1
CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_ERRNO = 0
CIRCUITPY_FRAMEBUFFERIO = 0
-CIRCUITPY_MSGPACK = 0
CIRCUITPY_GAMEPAD = 0
+CIRCUITPY_MSGPACK = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_NVM = 0
CIRCUITPY_PIXELBUF = 0
@@ -28,7 +30,6 @@ CIRCUITPY_SDCARDIO = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_ULAB = 0
CIRCUITPY_WATCHDOG = 1
-CIRCUITPY_BUSDEVICE = 0
# Enable micropython.native
#CIRCUITPY_ENABLE_MPY_NATIVE = 1
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index 4ed42cd82..3ac41a5e4 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -35,11 +35,8 @@
#include "peripherals/nrf/nvm.h" // for FLASH_PAGE_SIZE
#define MICROPY_PY_FUNCTION_ATTRS (1)
-#define MICROPY_PY_IO (1)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
#define MICROPY_PY_SYS_STDIO_BUFFER (1)
-#define MICROPY_PY_UBINASCII (1)
-#define MICROPY_PY_UJSON (1)
// 24kiB stack
#define CIRCUITPY_DEFAULT_STACK_SIZE (24*1024)
diff --git a/ports/raspberrypi/.gitignore b/ports/raspberrypi/.gitignore
new file mode 100644
index 000000000..414487d53
--- /dev/null
+++ b/ports/raspberrypi/.gitignore
@@ -0,0 +1 @@
+build-*/
diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile
new file mode 100644
index 000000000..a604acb47
--- /dev/null
+++ b/ports/raspberrypi/Makefile
@@ -0,0 +1,274 @@
+# This file is part of the MicroPython project, http://micropython.org/
+#
+# The MIT License (MIT)
+#
+# SPDX-FileCopyrightText: Copyright (c) 2019 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.
+
+# Select the board to build for.
+ifeq ($(BOARD),)
+ $(error You must provide a BOARD parameter)
+else
+ ifeq ($(wildcard boards/$(BOARD)/.),)
+ $(error Invalid BOARD specified)
+ endif
+endif
+
+# If the build directory is not given, make it reflect the board name.
+BUILD ?= build-$(BOARD)
+
+include ../../py/mkenv.mk
+# Board-specific
+include boards/$(BOARD)/mpconfigboard.mk
+# Port-specific
+include mpconfigport.mk
+# CircuitPython-specific
+include $(TOP)/py/circuitpy_mpconfig.mk
+
+# qstr definitions (must come before including py.mk)
+QSTR_DEFS = qstrdefsport.h
+
+# include py core make definitions
+include $(TOP)/py/py.mk
+
+include $(TOP)/supervisor/supervisor.mk
+
+# Include make rules and variables common across CircuitPython builds.
+include $(TOP)/py/circuitpy_defns.mk
+
+CROSS_COMPILE = arm-none-eabi-
+
+HAL_DIR=hal/$(MCU_SERIES)
+
+INC += -I. \
+ -I../.. \
+ -I../lib/mp-readline \
+ -I../lib/timeutils \
+ -Iboards/$(BOARD) \
+ -Iboards/ \
+ -isystem sdk/ \
+ -isystem sdk/src/common/pico_base/include/ \
+ -isystem sdk/src/common/pico_binary_info/include/ \
+ -isystem sdk/src/common/pico_stdlib/include/ \
+ -isystem sdk/src/common/pico_sync/include/ \
+ -isystem sdk/src/common/pico_time/include/ \
+ -isystem sdk/src/common/pico_util/include/ \
+ -isystem sdk/src/rp2040/hardware_regs/include/ \
+ -isystem sdk/src/rp2040/hardware_structs/include/ \
+ -isystem sdk/src/rp2_common/hardware_adc/include/ \
+ -isystem sdk/src/rp2_common/hardware_base/include/ \
+ -isystem sdk/src/rp2_common/hardware_claim/include/ \
+ -isystem sdk/src/rp2_common/hardware_clocks/include/ \
+ -isystem sdk/src/rp2_common/hardware_dma/include/ \
+ -isystem sdk/src/rp2_common/hardware_flash/include/ \
+ -isystem sdk/src/rp2_common/hardware_gpio/include/ \
+ -isystem sdk/src/rp2_common/hardware_irq/include/ \
+ -isystem sdk/src/rp2_common/hardware_i2c/include/ \
+ -isystem sdk/src/rp2_common/hardware_pio/include/ \
+ -isystem sdk/src/rp2_common/hardware_pll/include/ \
+ -isystem sdk/src/rp2_common/hardware_resets/include/ \
+ -isystem sdk/src/rp2_common/hardware_spi/include/ \
+ -isystem sdk/src/rp2_common/hardware_sync/include/ \
+ -isystem sdk/src/rp2_common/hardware_timer/include/ \
+ -isystem sdk/src/rp2_common/hardware_uart/include/ \
+ -isystem sdk/src/rp2_common/hardware_watchdog/include/ \
+ -isystem sdk/src/rp2_common/hardware_xosc/include/ \
+ -isystem sdk/src/rp2_common/pico_multicore/include/ \
+ -isystem sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/ \
+ -isystem sdk/src/rp2_common/pico_stdio/include/ \
+ -isystem sdk/src/rp2_common/pico_printf/include/ \
+ -isystem sdk/src/rp2_common/pico_float/include/ \
+ -isystem sdk/src/rp2_common/pico_platform/include/ \
+ -isystem sdk/src/rp2_common/pico_runtime/printf/include/ \
+ -isystem sdk/src/rp2_common/pico_bootrom/include/ \
+ -Isdk_config \
+ -I../../lib/tinyusb/src \
+ -I../../supervisor/shared/usb \
+ -I$(BUILD)
+
+# Pico specific configuration
+CFLAGS += -DPICO_ON_DEVICE=1 -DPICO_NO_BINARY_INFO=0 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1 -DPICO_DIVIDER_CALL_IDIV0=0 -DPICO_DIVIDER_CALL_LDIV0=0 -DPICO_DIVIDER_HARDWARE=1 -DPICO_DOUBLE_ROM=1 -DPICO_FLOAT_ROM=1 -DPICO_MULTICORE=1 -DPICO_BITS_IN_RAM=0 -DPICO_DIVIDER_IN_RAM=0 -DPICO_DOUBLE_PROPAGATE_NANS=0 -DPICO_DOUBLE_IN_RAM=0 -DPICO_MEM_IN_RAM=0 -DPICO_FLOAT_IN_RAM=0 -DPICO_FLOAT_PROPAGATE_NANS=1 -DPICO_NO_FLASH=0 -DPICO_COPY_TO_RAM=0 -DPICO_DISABLE_SHARED_IRQ_HANDLERS=0
+OPTIMIZATION_FLAGS ?= -O3
+# TinyUSB defines
+CFLAGS += -DTUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
+
+# option to override default optimization level, set in boards/$(BOARD)/mpconfigboard.mk
+CFLAGS += $(OPTIMIZATION_FLAGS)
+
+#Debugging/Optimization
+ifeq ($(DEBUG), 1)
+ CFLAGS += -ggdb3 -Og
+ # No LTO because we may place some functions in RAM instead of flash.
+else
+ CFLAGS += -DNDEBUG
+
+ # No LTO because we may place some functions in RAM instead of flash.
+
+ ifdef CFLAGS_BOARD
+ CFLAGS += $(CFLAGS_BOARD)
+ endif
+endif
+
+# Remove -Wno-stringop-overflow after we can test with CI's GCC 10. Mac's looks weird.
+DISABLE_WARNINGS = -Wno-stringop-overflow -Wno-unused-function -Wno-unused-variable -Wno-strict-overflow -Wno-cast-align -Wno-strict-prototypes -Wno-nested-externs -Wno-double-promotion -Wno-sign-compare
+
+CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS)
+
+CFLAGS += \
+ -march=armv6-m \
+ -mthumb \
+ -mabi=aapcs-linux \
+ -mcpu=cortex-m0plus \
+ -msoft-float \
+ -mfloat-abi=soft
+
+PICO_LDFLAGS = --specs=nosys.specs -Wl,--wrap=__aeabi_ldiv0 -Wl,--wrap=__aeabi_idiv0 -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8
+
+LDFLAGS = $(CFLAGS) $(PICO_LDFLAGS) -Wl,-T,link.ld -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections
+
+# Use toolchain libm if we're not using our own.
+ifndef INTERNAL_LIBM
+LIBS += -lm
+endif
+
+LDFLAGS += -mthumb -mcpu=cortex-m0plus
+
+SRC_SDK := \
+ src/common/pico_sync/critical_section.c \
+ src/common/pico_sync/lock_core.c \
+ src/common/pico_sync/mutex.c \
+ src/common/pico_time/time.c \
+ src/common/pico_util/pheap.c \
+ src/rp2_common/hardware_adc/adc.c \
+ src/rp2_common/hardware_claim/claim.c \
+ src/rp2_common/hardware_clocks/clocks.c \
+ src/rp2_common/hardware_dma/dma.c \
+ src/rp2_common/hardware_flash/flash.c \
+ src/rp2_common/hardware_gpio/gpio.c \
+ src/rp2_common/hardware_i2c/i2c.c \
+ src/rp2_common/hardware_irq/irq.c \
+ src/rp2_common/hardware_pio/pio.c \
+ src/rp2_common/hardware_pll/pll.c \
+ src/rp2_common/hardware_spi/spi.c \
+ src/rp2_common/hardware_sync/sync.c \
+ src/rp2_common/hardware_timer/timer.c \
+ src/rp2_common/hardware_uart/uart.c \
+ src/rp2_common/hardware_watchdog/watchdog.c \
+ src/rp2_common/hardware_xosc/xosc.c \
+ src/rp2_common/pico_bootrom/bootrom.c \
+ src/rp2_common/pico_double/double_init_rom.c \
+ src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c \
+ src/rp2_common/pico_float/float_init_rom.c \
+ src/rp2_common/pico_float/float_math.c \
+ src/rp2_common/pico_multicore/multicore.c \
+ src/rp2_common/pico_platform/platform.c \
+ src/rp2_common/pico_printf/printf.c \
+ src/rp2_common/pico_runtime/runtime.c \
+ src/rp2_common/pico_stdio/stdio.c \
+
+SRC_SDK := $(addprefix sdk/, $(SRC_SDK))
+
+SRC_C += \
+ boards/$(BOARD)/board.c \
+ boards/$(BOARD)/pins.c \
+ bindings/rp2pio/StateMachine.c \
+ bindings/rp2pio/__init__.c \
+ common-hal/rp2pio/StateMachine.c \
+ common-hal/rp2pio/__init__.c \
+ background.c \
+ peripherals/pins.c \
+ fatfs_port.c \
+ lib/libc/string0.c \
+ lib/mp-readline/readline.c \
+ lib/oofatfs/ff.c \
+ lib/oofatfs/option/ccsbcs.c \
+ lib/timeutils/timeutils.c \
+ lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \
+ lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \
+ lib/utils/buffer_helper.c \
+ lib/utils/context_manager_helpers.c \
+ lib/utils/interrupt_char.c \
+ lib/utils/pyexec.c \
+ lib/utils/stdout_helpers.c \
+ lib/utils/sys_stdio_mphal.c \
+ mphalport.c \
+ supervisor/shared/memory.c \
+
+SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
+ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
+ $(addprefix common-hal/, $(SRC_COMMON_HAL))
+
+SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
+ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \
+ $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL))
+
+# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED,
+# because a few modules have files both in common-hal/ and shared-modules/.
+# Doing a $(sort ...) removes duplicates as part of sorting.
+SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED))
+
+SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s
+SRC_S_UPPER = bs2_default_padded_checksummed.S \
+ sdk/src/rp2_common/hardware_divider/divider.S \
+ sdk/src/rp2_common/hardware_irq/irq_handler_chain.S \
+ sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S \
+ sdk/src/rp2_common/pico_double/double_aeabi.S \
+ sdk/src/rp2_common/pico_double/double_v1_rom_shim.S \
+ sdk/src/rp2_common/pico_divider/divider.S \
+ sdk/src/rp2_common/pico_float/float_aeabi.S \
+ sdk/src/rp2_common/pico_float/float_v1_rom_shim.S \
+ sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S \
+ sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S \
+ sdk/src/rp2_common/pico_standard_link/crt0.S \
+
+OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_SDK:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
+ifeq ($(INTERNAL_LIBM),1)
+OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
+endif
+OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o))
+OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
+
+
+SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)
+
+all: $(BUILD)/firmware.uf2
+
+$(BUILD)/firmware.elf: $(OBJ) link.ld
+ $(STEPECHO) "LINK $@"
+ $(Q)$(CC) -o $@ $(LDFLAGS) $(OBJ)
+ $(Q)$(SIZE) $@ | $(PYTHON3) $(TOP)/tools/build_memory_info.py link.ld
+
+$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
+ $(STEPECHO) "Create $@"
+ $(Q)$(OBJCOPY) -O binary $^ $@
+
+$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
+ $(STEPECHO) "Create $@"
+ $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xe48bff56 -b 0x10000000 -c -o $@ $^
+
+include $(TOP)/py/mkrules.mk
+
+# Print out the value of a make variable.
+# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile
+print-%:
+ @echo $* = $($*)
diff --git a/ports/raspberrypi/README.rst b/ports/raspberrypi/README.rst
new file mode 100644
index 000000000..d6ad9b333
--- /dev/null
+++ b/ports/raspberrypi/README.rst
@@ -0,0 +1,18 @@
+RP2040
+==================
+
+This port supports many development boards that utilize RP2040 chips. See
+https://circuitpython.org/downloads for all supported boards.
+
+
+Building
+--------
+
+For build instructions see this guide: https://learn.adafruit.com/building-circuitpython/
+
+
+Port Specific modules
+---------------------
+
+.. toctree::
+ ../../shared-bindings/rp2pio/index
diff --git a/ports/raspberrypi/background.c b/ports/raspberrypi/background.c
new file mode 100644
index 000000000..c85b83b41
--- /dev/null
+++ b/ports/raspberrypi/background.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 "background.h"
+
+#include "supervisor/filesystem.h"
+#include "supervisor/shared/tick.h"
+#include "supervisor/usb.h"
+
+#include "py/runtime.h"
+#include "shared-module/network/__init__.h"
+#include "supervisor/shared/stack.h"
+#include "supervisor/port.h"
+
+#if CIRCUITPY_DISPLAYIO
+#include "shared-module/displayio/__init__.h"
+#endif
+
+void port_start_background_task(void) {}
+void port_finish_background_task(void) {}
+
+void port_background_task(void) {}
diff --git a/ports/raspberrypi/background.h b/ports/raspberrypi/background.h
new file mode 100644
index 000000000..c8e23e2a5
--- /dev/null
+++ b/ports/raspberrypi/background.h
@@ -0,0 +1,32 @@
+/*
+ * 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_BACKGROUND_H
+#define MICROPY_INCLUDED_RASPBERRYPI_BACKGROUND_H
+
+#include <stdbool.h>
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_BACKGROUND_H
diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c
new file mode 100644
index 000000000..0f6f84a56
--- /dev/null
+++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c
@@ -0,0 +1,449 @@
+/*
+ * 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.
+ */
+
+// This file contains all of the Python API definitions for the
+// rp2pio.StateMachine class.
+
+#include <string.h>
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "bindings/rp2pio/StateMachine.h"
+#include "shared-bindings/util.h"
+
+#include "lib/utils/buffer_helper.h"
+#include "lib/utils/context_manager_helpers.h"
+#include "lib/utils/interrupt_char.h"
+#include "py/mperrno.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+
+//| class StateMachine:
+//| """A single PIO StateMachine
+//|
+//| The programmable I/O peripheral on the RP2 series of microcontrollers is
+//| unique. It is a collection of generic state machines that can be
+//| used for a variety of protocols. State machines may be independent or
+//| coordinated. Program memory and IRQs are shared between the state machines
+//| in a particular PIO instance. They are independent otherwise.
+//|
+//| This class is designed to facilitate sharing of PIO resources. By default,
+//| it is assumed that the state machine is used on its own and can be placed
+//| in either PIO. State machines with the same program will be placed in the
+//| same PIO if possible. To ensure multiple state machines share a PIO use
+//| the ``colocate`` kwarg during construction and create them one after another."""
+//|
+//| def __init__(self,
+//| program: ReadableBuffer,
+//| frequency: int,
+//| *,
+//| init: Optional[ReadableBuffer] = None,
+//| first_out_pin: Optional[microcontroller.Pin] = None,
+//| out_pin_count: int = 1,
+//| first_in_pin: Optional[microcontroller.Pin] = None,
+//| in_pin_count: int = 1,
+//| first_set_pin: Optional[microcontroller.Pin] = None,
+//| set_pin_count: int = 1,
+//| first_sideset_pin: Optional[microcontroller.Pin] = None,
+//| sideset_pin_count: int = 1,
+//| exclusive_pin_use: bool = True,
+//| auto_pull: bool = False,
+//| pull_threshold : int = 32,
+//| out_shift_right : bool = True,
+//| auto_push: bool = False,
+//| push_threshold : int = 32,
+//| in_shift_right : bool = True) -> None:
+// //| colocate: Union[int, StateMachine, None] = None
+//|
+//| """Construct a StateMachine object on the given pins with the given program.
+//|
+//| :param ReadableBuffer program: the program to run with the state machine
+//| :param int frequency: the target clock frequency of the state machine. Actual may be less.
+//| :param ReadableBuffer init: a program to run once at start up. This is run after program
+//| is started so instructions may be intermingled
+//| :param ~microcontroller.Pin first_out_pin: the first pin to use with the OUT instruction
+//| :param int out_pin_count: the count of consecutive pins to use with OUT starting at first_out_pin
+//| :param ~microcontroller.Pin first_in_pin: the first pin to use with the IN instruction
+//| :param int in_pin_count: the count of consecutive pins to use with IN starting at first_in_pin
+//| :param ~microcontroller.Pin first_set_pin: the first pin to use with the SET instruction
+//| :param int set_pin_count: the count of consecutive pins to use with SET starting at first_set_pin
+//| :param ~microcontroller.Pin first_sideset_pin: the first pin to use with a side set
+//| :param int sideset_pin_count: the count of consecutive pins to use with a side set starting at first_sideset_pin
+//| :param bool exclusive_pin_use: When True, do not share any pins with other state machines. Pins are never shared with other peripherals
+//| :param bool auto_pull: When True, automatically load data from the tx FIFO into the
+//| output shift register (OSR) when an OUT instruction shifts more than pull_threshold bits
+//| :param int pull_threshold: Number of bits to shift before loading a new value into the OSR from the tx FIFO
+//| :param bool out_shift_right: When True, data is shifted out the right side (LSB) of the
+//| OSR. It is shifted out the left (MSB) otherwise. NOTE! This impacts data alignment
+//| when the number of bytes is not a power of two (1, 2 or 4 bytes).
+//| :param bool auto_push: When True, automatically save data from input shift register
+//| (ISR) into the rx FIFO when an IN instruction shifts more than push_threshold bits
+//| :param int push_threshold: Number of bits to shift before saving the ISR value to the RX FIFO
+//| :param bool in_shift_right: When True, data is shifted into the right side (LSB) of the
+//| ISR. It is shifted into the left (MSB) otherwise. NOTE! This impacts data alignment
+//| when the number of bytes is not a power of two (1, 2 or 4 bytes)."""
+//| ...
+//|
+
+STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ rp2pio_statemachine_obj_t *self = m_new_obj(rp2pio_statemachine_obj_t);
+ self->base.type = &rp2pio_statemachine_type;
+ enum { ARG_program, ARG_frequency, ARG_init,
+ ARG_first_out_pin, ARG_out_pin_count,
+ ARG_first_in_pin, ARG_in_pin_count,
+ ARG_first_set_pin, ARG_set_pin_count,
+ ARG_first_sideset_pin, ARG_sideset_pin_count,
+ ARG_exclusive_pin_use,
+ ARG_auto_pull, ARG_pull_threshold, ARG_out_shift_right,
+ ARG_auto_push, ARG_push_threshold, ARG_in_shift_right};
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT },
+ { MP_QSTR_init, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_first_out_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_out_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
+ { MP_QSTR_first_in_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_in_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
+ { MP_QSTR_first_set_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_set_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
+ { MP_QSTR_first_sideset_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_sideset_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
+ { MP_QSTR_exclusive_pin_use, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ { MP_QSTR_auto_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_pull_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
+ { MP_QSTR_out_shift_right, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ { MP_QSTR_auto_push, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_push_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
+ { MP_QSTR_in_shift_right, 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_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_program].u_obj, &bufinfo, MP_BUFFER_READ);
+
+ mp_buffer_info_t init_bufinfo;
+ init_bufinfo.len = 0;
+ mp_get_buffer(args[ARG_init].u_obj, &init_bufinfo, MP_BUFFER_READ);
+
+ // We don't validate pin in use here because we may be ok sharing them within a PIO.
+ mcu_pin_obj_t *first_out_pin = validate_obj_is_pin_or_none(args[ARG_first_out_pin].u_obj);
+ if (args[ARG_out_pin_count].u_int < 1) {
+ mp_raise_ValueError(translate("Pin count must be at least 1"));
+ }
+ mcu_pin_obj_t *first_in_pin = validate_obj_is_pin_or_none(args[ARG_first_in_pin].u_obj);
+ if (args[ARG_in_pin_count].u_int < 1) {
+ mp_raise_ValueError(translate("Pin count must be at least 1"));
+ }
+ mcu_pin_obj_t *first_set_pin = validate_obj_is_pin_or_none(args[ARG_first_set_pin].u_obj);
+ if (args[ARG_set_pin_count].u_int < 1) {
+ mp_raise_ValueError(translate("Pin count must be at least 1"));
+ }
+ if (args[ARG_set_pin_count].u_int > 5) {
+ mp_raise_ValueError(translate("Set pin count must be between 1 and 5"));
+ }
+ mcu_pin_obj_t *first_sideset_pin = validate_obj_is_pin_or_none(args[ARG_first_sideset_pin].u_obj);
+ if (args[ARG_sideset_pin_count].u_int < 1) {
+ mp_raise_ValueError(translate("Pin count must be at least 1"));
+ }
+ if (args[ARG_sideset_pin_count].u_int > 5) {
+ mp_raise_ValueError(translate("Side set pin count must be between 1 and 5"));
+ }
+
+ mp_int_t pull_threshold = args[ARG_pull_threshold].u_int;
+ mp_int_t push_threshold = args[ARG_push_threshold].u_int;
+ if (pull_threshold < 1 || pull_threshold > 32) {
+ mp_raise_ValueError(translate("pull_threshold must be between 1 and 32"));
+ }
+ if (push_threshold < 1 || push_threshold > 32) {
+ mp_raise_ValueError(translate("push_threshold must be between 1 and 32"));
+ }
+
+ if (bufinfo.len < 2) {
+ mp_raise_ValueError(translate("Program must contain at least one 16-bit instruction."));
+ }
+ if (bufinfo.len % 2 != 0) {
+ mp_raise_ValueError(translate("Program size invalid"));
+ }
+ if (bufinfo.len > 32) {
+ mp_raise_ValueError(translate("Program too large"));
+ }
+
+ if (init_bufinfo.len % 2 != 0) {
+ mp_raise_ValueError(translate("Init program size invalid"));
+ }
+
+ common_hal_rp2pio_statemachine_construct(self,
+ bufinfo.buf, bufinfo.len / 2,
+ args[ARG_frequency].u_int,
+ init_bufinfo.buf, init_bufinfo.len / 2,
+ first_out_pin, args[ARG_out_pin_count].u_int,
+ first_in_pin, args[ARG_in_pin_count].u_int,
+ first_set_pin, args[ARG_set_pin_count].u_int,
+ first_sideset_pin, args[ARG_sideset_pin_count].u_int,
+ args[ARG_exclusive_pin_use].u_bool,
+ args[ARG_auto_pull].u_bool, pull_threshold, args[ARG_out_shift_right].u_bool,
+ args[ARG_auto_push].u_bool, push_threshold, args[ARG_in_shift_right].u_bool);
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| def deinit(self) -> None:
+//| """Turn off the state machine and release its resources."""
+//| ...
+//|
+STATIC mp_obj_t rp2pio_statemachine_obj_deinit(mp_obj_t self_in) {
+ rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_rp2pio_statemachine_deinit(self);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_deinit_obj, rp2pio_statemachine_obj_deinit);
+
+//| def __enter__(self) -> StateMachine:
+//| """No-op used by Context Managers.
+//| Provided by context manager helper."""
+//| ...
+//|
+
+//| def __exit__(self) -> None:
+//| """Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info."""
+//| ...
+//|
+STATIC mp_obj_t rp2pio_statemachine_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_rp2pio_statemachine_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rp2pio_statemachine_obj___exit___obj, 4, 4, rp2pio_statemachine_obj___exit__);
+
+
+STATIC void check_for_deinit(rp2pio_statemachine_obj_t *self) {
+ if (common_hal_rp2pio_statemachine_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+// // | def restart(self, *other_state_machines) -> None:
+// // | """Restarts this state machine and any others given. They must share
+// // | an underlying PIO. An exception will be raised otherwise."""
+// // | ...
+// // |
+
+//| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
+//| """Write the data contained in ``buffer`` to the state machine. If the buffer is empty, nothing happens.
+//|
+//| :param ~_typing.ReadableBuffer buffer: Write out the data in this buffer
+//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
+//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``"""
+//| ...
+//|
+
+STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_buffer, ARG_start, ARG_end };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
+ };
+ rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ check_for_deinit(self);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ);
+ int32_t start = args[ARG_start].u_int;
+ size_t length = bufinfo.len;
+ normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
+
+ if (length == 0) {
+ return mp_const_none;
+ }
+
+ bool ok = common_hal_rp2pio_statemachine_write(self, ((uint8_t*)bufinfo.buf) + start, length);
+ if (mp_hal_is_interrupted()) {
+ return mp_const_none;
+ }
+ if (!ok) {
+ mp_raise_OSError(MP_EIO);
+ }
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine_write);
+
+
+// // | def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
+// // | """Read into ``buffer``. If the number of bytes to read is 0, nothing happens.
+// // |
+// // | :param ~_typing.WriteableBuffer buffer: Read data into this buffer
+// // | :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]``
+// // | :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
+// // | :param int write_value: Value to write while reading. (Usually ignored.)"""
+// // | ...
+// // |
+
+// STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+// enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value };
+// static const mp_arg_t allowed_args[] = {
+// { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+// { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+// { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
+// { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+// };
+// rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+// check_for_deinit(self);
+// check_lock(self);
+// mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+// mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+// mp_buffer_info_t bufinfo;
+// mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE);
+// int32_t start = args[ARG_start].u_int;
+// size_t length = bufinfo.len;
+// normalize_buffer_bounds(&start, args[ARG_end].u_int, &length);
+
+// if (length == 0) {
+// return mp_const_none;
+// }
+
+// bool ok = common_hal_rp2pio_statemachine_read(self, ((uint8_t*)bufinfo.buf) + start, length, args[ARG_write_value].u_int);
+// if (!ok) {
+// mp_raise_OSError(MP_EIO);
+// }
+// return mp_const_none;
+// }
+// MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_readinto_obj, 2, rp2pio_statemachine_readinto);
+
+// //| def write_readinto(self, buffer_out: ReadableBuffer, buffer_in: WriteableBuffer, *, out_start: int = 0, out_end: Optional[int] = None, in_start: int = 0, in_end: Optional[int] = None) -> None:
+// //| """Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
+// //| The SPI object must be locked.
+// //| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]``
+// //| must be equal.
+// //| If buffer slice lengths are both 0, nothing happens.
+// //|
+// //| :param ~_typing.ReadableBuffer buffer_out: Write out the data in this buffer
+// //| :param ~_typing.WriteableBuffer buffer_in: Read data into this buffer
+// //| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
+// //| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
+// //| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
+// //| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``"""
+// //| ...
+// //|
+
+// STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+// enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
+// static const mp_arg_t allowed_args[] = {
+// { MP_QSTR_buffer_out, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+// { MP_QSTR_buffer_in, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+// { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+// { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
+// { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+// { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
+// };
+// rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+// check_for_deinit(self);
+// check_lock(self);
+// mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+// mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+// mp_buffer_info_t buf_out_info;
+// mp_get_buffer_raise(args[ARG_buffer_out].u_obj, &buf_out_info, MP_BUFFER_READ);
+// int32_t out_start = args[ARG_out_start].u_int;
+// size_t out_length = buf_out_info.len;
+// normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length);
+
+// mp_buffer_info_t buf_in_info;
+// mp_get_buffer_raise(args[ARG_buffer_in].u_obj, &buf_in_info, MP_BUFFER_WRITE);
+// int32_t in_start = args[ARG_in_start].u_int;
+// size_t in_length = buf_in_info.len;
+// normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length);
+
+// if (out_length != in_length) {
+// mp_raise_ValueError(translate("buffer slices must be of equal length"));
+// }
+
+// if (out_length == 0) {
+// return mp_const_none;
+// }
+
+// bool ok = common_hal_rp2pio_statemachine_transfer(self,
+// ((uint8_t*)buf_out_info.buf) + out_start,
+// ((uint8_t*)buf_in_info.buf) + in_start,
+// out_length);
+// if (!ok) {
+// mp_raise_OSError(MP_EIO);
+// }
+// return mp_const_none;
+// }
+// MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_readinto_obj, 2, rp2pio_statemachine_write_readinto);
+
+//| frequency: int
+//| """The actual state machine frequency. This may not match the frequency requested
+//| due to internal limitations."""
+//|
+
+STATIC mp_obj_t rp2pio_statemachine_obj_get_frequency(mp_obj_t self_in) {
+ rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_rp2pio_statemachine_get_frequency(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_frequency_obj, rp2pio_statemachine_obj_get_frequency);
+
+const mp_obj_property_t rp2pio_statemachine_frequency_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&rp2pio_statemachine_get_frequency_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rp2pio_statemachine_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rp2pio_statemachine_obj___exit___obj) },
+
+// { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&rp2pio_statemachine_configure_obj) },
+
+// { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&rp2pio_statemachine_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&rp2pio_statemachine_write_obj) },
+// { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&rp2pio_statemachine_write_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&rp2pio_statemachine_frequency_obj) }
+};
+STATIC MP_DEFINE_CONST_DICT(rp2pio_statemachine_locals_dict, rp2pio_statemachine_locals_dict_table);
+
+const mp_obj_type_t rp2pio_statemachine_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_StateMachine,
+ .make_new = rp2pio_statemachine_make_new,
+ .locals_dict = (mp_obj_dict_t*)&rp2pio_statemachine_locals_dict,
+};
+
+rp2pio_statemachine_obj_t *validate_obj_is_statemachine(mp_obj_t obj) {
+ if (!MP_OBJ_IS_TYPE(obj, &rp2pio_statemachine_type)) {
+ mp_raise_TypeError_varg(translate("Expected a %q"), rp2pio_statemachine_type.name);
+ }
+ return MP_OBJ_TO_PTR(obj);
+}
diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.h b/ports/raspberrypi/bindings/rp2pio/StateMachine.h
new file mode 100644
index 000000000..5ff20a75b
--- /dev/null
+++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.h
@@ -0,0 +1,71 @@
+/*
+ * 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_BINDINGS_RP2PIO_STATEMACHINE_H
+#define MICROPY_INCLUDED_RASPBERRYPI_BINDINGS_RP2PIO_STATEMACHINE_H
+
+#include "py/obj.h"
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/rp2pio/StateMachine.h"
+
+// Type object used in Python. Should be shared between ports.
+extern const mp_obj_type_t rp2pio_statemachine_type;
+
+// Construct an underlying SPI object.
+extern void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
+ const uint16_t* program, size_t program_len,
+ size_t frequency,
+ const uint16_t* init, size_t init_len,
+ const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
+ const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
+ const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
+ const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
+ bool exclusive_pin_use,
+ bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
+ bool auto_push, uint8_t push_threshold, bool in_shift_right);
+
+extern void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
+extern bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);
+
+// Writes out the given data.
+extern bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len);
+
+// // Reads in len bytes while outputting zeroes.
+// extern bool common_hal_rp2pio_statemachine_read(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t write_value);
+
+// // Reads and write len bytes simultaneously.
+// extern bool common_hal_rp2pio_statemachine_transfer(rp2pio_statemachine_obj_t *self,
+// const uint8_t *data_out, size_t out_len,
+// uint8_t *data_in, size_t in_len);
+
+// Return actual SPI bus frequency.
+uint32_t common_hal_rp2pio_statemachine_get_frequency(rp2pio_statemachine_obj_t* self);
+
+// This is used by the supervisor to claim SPI devices indefinitely.
+// extern void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_BINDINGS_RP2PIO_STATEMACHINE_H
diff --git a/ports/raspberrypi/bindings/rp2pio/__init__.c b/ports/raspberrypi/bindings/rp2pio/__init__.c
new file mode 100644
index 000000000..dd5808cd5
--- /dev/null
+++ b/ports/raspberrypi/bindings/rp2pio/__init__.c
@@ -0,0 +1,45 @@
+/*
+ * 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 "py/obj.h"
+#include "py/runtime.h"
+
+#include "bindings/rp2pio/StateMachine.h"
+
+//| """Hardware interface to RP2 series' programmable IO (PIO) peripheral."""
+//|
+
+STATIC const mp_rom_map_elem_t rp2pio_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rp2pio) },
+ { MP_ROM_QSTR(MP_QSTR_StateMachine), MP_ROM_PTR(&rp2pio_statemachine_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(rp2pio_module_globals, rp2pio_module_globals_table);
+
+const mp_obj_module_t rp2pio_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&rp2pio_module_globals,
+};
diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040/board.c
new file mode 100644
index 000000000..8686f6d0c
--- /dev/null
+++ b/ports/raspberrypi/boards/adafruit_feather_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_GPIO17);
+ gpio_init(17);
+ gpio_set_dir(17, GPIO_OUT);
+ gpio_put(17, true);
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h
new file mode 100644
index 000000000..6a2d063d7
--- /dev/null
+++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.h
@@ -0,0 +1,14 @@
+#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040"
+#define MICROPY_HW_MCU_NAME "rp2040"
+
+#define MICROPY_HW_NEOPIXEL (&pin_GPIO16)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18)
+#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19)
+#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20)
+
+// #define DEFAULT_UART_BUS_RX (&pin_PA11)
+// #define DEFAULT_UART_BUS_TX (&pin_PA10)
diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.mk
new file mode 100644
index 000000000..f4106b94a
--- /dev/null
+++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/mpconfigboard.mk
@@ -0,0 +1,9 @@
+USB_VID = 0x239A
+USB_PID = 0x80F2
+USB_PRODUCT = "Feather RP2040"
+USB_MANUFACTURER = "Adafruit"
+
+CHIP_VARIANT = RP2040
+CHIP_FAMILY = rp2
+
+INTERNAL_FLASH_FILESYSTEM = 1
diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040/pins.c
new file mode 100644
index 000000000..1617ac865
--- /dev/null
+++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/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_A0), MP_ROM_PTR(&pin_GPIO26) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) },
+ { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) },
+ { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) },
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) },
+ { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) },
+
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO17) },
+
+ { 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/board.c b/ports/raspberrypi/boards/raspberry_pi_pico/board.c
new file mode 100644
index 000000000..80ec5de32
--- /dev/null
+++ b/ports/raspberrypi/boards/raspberry_pi_pico/board.c
@@ -0,0 +1,38 @@
+/*
+ * 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/raspberry_pi_pico/mpconfigboard.h b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h
new file mode 100644
index 000000000..4b0a22028
--- /dev/null
+++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.h
@@ -0,0 +1,15 @@
+// LEDs
+// #define MICROPY_HW_LED_STATUS (&pin_PA17)
+
+#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico"
+#define MICROPY_HW_MCU_NAME "rp2040"
+
+// #define DEFAULT_I2C_BUS_SCL (&pin_PA23)
+// #define DEFAULT_I2C_BUS_SDA (&pin_PA22)
+
+// #define DEFAULT_SPI_BUS_SCK (&pin_PB11)
+// #define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
+// #define DEFAULT_SPI_BUS_MISO (&pin_PA12)
+
+// #define DEFAULT_UART_BUS_RX (&pin_PA11)
+// #define DEFAULT_UART_BUS_TX (&pin_PA10)
diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk
new file mode 100644
index 000000000..69ff56fef
--- /dev/null
+++ b/ports/raspberrypi/boards/raspberry_pi_pico/mpconfigboard.mk
@@ -0,0 +1,9 @@
+USB_VID = 0x239A
+USB_PID = 0x80F4
+USB_PRODUCT = "Pico"
+USB_MANUFACTURER = "Raspberry Pi"
+
+CHIP_VARIANT = RP2040
+CHIP_FAMILY = rp2
+
+INTERNAL_FLASH_FILESYSTEM = 1
diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico/pins.c
new file mode 100644
index 000000000..913676ad2
--- /dev/null
+++ b/ports/raspberrypi/boards/raspberry_pi_pico/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_GP8), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) },
+ { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) },
+ { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) },
+ { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) },
+ { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) },
+ { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) },
+ { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) },
+ { 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_A0), MP_ROM_PTR(&pin_GPIO26) },
+ { 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_A1), MP_ROM_PTR(&pin_GPIO27) },
+ { 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_A2), MP_ROM_PTR(&pin_GPIO28) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/raspberrypi/bs2_default_padded_checksummed.S b/ports/raspberrypi/bs2_default_padded_checksummed.S
new file mode 100644
index 000000000..d77f4867c
--- /dev/null
+++ b/ports/raspberrypi/bs2_default_padded_checksummed.S
@@ -0,0 +1,20 @@
+// Padded and checksummed version of: /Users/graham/dev/mu/pico_sdk/cmake-build-debug-mu/src/rp2_common/boot_stage2/bs2_default.bin
+
+.section .boot2, "a"
+
+.byte 0x00, 0xb5, 0x2f, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21, 0x88, 0x43, 0x98, 0x60
+.byte 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2b, 0x4b, 0x00, 0x21, 0x99, 0x60, 0x02, 0x21, 0x59, 0x61
+.byte 0x01, 0x21, 0xf0, 0x22, 0x99, 0x50, 0x28, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20
+.byte 0x00, 0xf0, 0x3e, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21, 0x19, 0x66, 0x00, 0xf0
+.byte 0x2e, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0
+.byte 0x26, 0xf8, 0x19, 0x6e, 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x29, 0xf8, 0x01, 0x21
+.byte 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x18, 0x49, 0x19, 0x60, 0x00, 0x21, 0x59, 0x60
+.byte 0x17, 0x49, 0x18, 0x48, 0x01, 0x60, 0x01, 0x21, 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21
+.byte 0x19, 0x66, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x13, 0x49, 0x11, 0x48, 0x01, 0x60
+.byte 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd1, 0x10, 0x48, 0x00, 0x47, 0x03, 0xb5
+.byte 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd
+.byte 0x02, 0xb5, 0x18, 0x66, 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd
+.byte 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x5f, 0x00
+.byte 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, 0x22, 0x20, 0x00, 0xa0, 0x01, 0x01, 0x00, 0x10
+.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x27, 0x2a, 0x60
diff --git a/ports/raspberrypi/common-hal/analogio/AnalogIn.c b/ports/raspberrypi/common-hal/analogio/AnalogIn.c
new file mode 100644
index 000000000..c51a74929
--- /dev/null
+++ b/ports/raspberrypi/common-hal/analogio/AnalogIn.c
@@ -0,0 +1,73 @@
+/*
+ * 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 "common-hal/analogio/AnalogIn.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+#include "src/rp2_common/hardware_adc/include/hardware/adc.h"
+
+#define ADC_FIRST_PIN_NUMBER 26
+#define ADC_PIN_COUNT 4
+
+void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) {
+ if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number > ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT) {
+ mp_raise_ValueError(translate("Pin does not have ADC capabilities"));
+ }
+
+ adc_init();
+
+ adc_gpio_init(pin->number);
+
+ claim_pin(pin);
+ self->pin = pin;
+}
+
+bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) {
+ return self->pin == NULL;
+}
+
+void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
+ if (common_hal_analogio_analogin_deinited(self)) {
+ return;
+ }
+
+ reset_pin_number(self->pin->number);
+ self->pin = NULL;
+}
+
+uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
+ adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
+ uint16_t value = adc_read();
+
+ // Map value to from 12 to 16 bits
+ return (value << 4);
+}
+
+float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) {
+ // The nominal VCC voltage
+ return 3.3f;
+}
diff --git a/ports/raspberrypi/common-hal/analogio/AnalogIn.h b/ports/raspberrypi/common-hal/analogio/AnalogIn.h
new file mode 100644
index 000000000..ee9976e34
--- /dev/null
+++ b/ports/raspberrypi/common-hal/analogio/AnalogIn.h
@@ -0,0 +1,41 @@
+/*
+ * 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_COMMON_HAL_ANALOGIO_ANALOGIN_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGIO_ANALOGIN_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ const mcu_pin_obj_t * pin;
+} analogio_analogin_obj_t;
+
+void analogin_init(void);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGIO_ANALOGIN_H
diff --git a/ports/raspberrypi/common-hal/analogio/AnalogOut.c b/ports/raspberrypi/common-hal/analogio/AnalogOut.c
new file mode 100644
index 000000000..adafa15d5
--- /dev/null
+++ b/ports/raspberrypi/common-hal/analogio/AnalogOut.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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 "shared-bindings/analogio/AnalogOut.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "py/mperrno.h"
+#include "py/runtime.h"
+#include "supervisor/shared/translate.h"
+
+void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin) {
+ mp_raise_RuntimeError(translate("AnalogOut functionality not supported"));
+}
+
+bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
+ return true;
+}
+
+void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) {
+}
+
+void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value) {
+}
diff --git a/ports/raspberrypi/common-hal/analogio/AnalogOut.h b/ports/raspberrypi/common-hal/analogio/AnalogOut.h
new file mode 100644
index 000000000..7c7a61aa2
--- /dev/null
+++ b/ports/raspberrypi/common-hal/analogio/AnalogOut.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft
+ *
+ * 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_ANALOGIO_ANALOGOUT_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGIO_ANALOGOUT_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+} analogio_analogout_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_ANALOGIO_ANALOGOUT_H
diff --git a/ports/raspberrypi/common-hal/analogio/__init__.c b/ports/raspberrypi/common-hal/analogio/__init__.c
new file mode 100644
index 000000000..eea58c77d
--- /dev/null
+++ b/ports/raspberrypi/common-hal/analogio/__init__.c
@@ -0,0 +1 @@
+// No analogio module functions.
diff --git a/ports/raspberrypi/common-hal/board/__init__.c b/ports/raspberrypi/common-hal/board/__init__.c
new file mode 100644
index 000000000..3c7f30df2
--- /dev/null
+++ b/ports/raspberrypi/common-hal/board/__init__.c
@@ -0,0 +1,34 @@
+/*
+ * 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 <string.h>
+
+#include "py/runtime.h"
+#include "py/mphal.h"
+#include "common-hal/microcontroller/Pin.h"
+
+// Pins aren't actually defined here. They are in the board specific directory
+// such as boards/arduino_zero/pins.c.
diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c
new file mode 100644
index 000000000..fa49e375e
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/I2C.c
@@ -0,0 +1,175 @@
+/*
+ * 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 "shared-bindings/busio/I2C.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+#include "supervisor/shared/translate.h"
+
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+
+// Synopsys DW_apb_i2c (v2.01) IP
+
+#define NO_PIN 0xff
+
+STATIC bool never_reset_i2c[2];
+STATIC i2c_inst_t* i2c[2] = {i2c0, i2c1};
+
+void reset_i2c(void) {
+ for (size_t i = 0; i < 2; i++) {
+ if (never_reset_i2c[i]) {
+ continue;
+ }
+
+ i2c_deinit(i2c[i]);
+ }
+}
+
+void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
+ const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) {
+ self->peripheral = NULL;
+ // I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs
+ // so we can divide by two to get the instance. This pattern repeats.
+ if (scl->number % 2 == 1 && sda->number % 2 == 0 && scl->number / 2 == sda->number / 2) {
+ size_t instance = (scl->number / 2) % 2;
+ self->peripheral = i2c[instance];
+ }
+ if (self->peripheral == NULL) {
+ mp_raise_ValueError(translate("Invalid pins"));
+ }
+ if ((i2c_get_hw(self->peripheral)->enable & I2C_IC_ENABLE_ENABLE_BITS) != 0) {
+ mp_raise_ValueError(translate("I2C peripheral in use"));
+ }
+ if (frequency > 1000000) {
+ mp_raise_ValueError(translate("Unsupported baudrate"));
+ }
+
+#if CIRCUITPY_REQUIRE_I2C_PULLUPS
+ // Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
+ gpio_set_function(sda->number, GPIO_FUNC_SIO);
+ gpio_set_function(scl->number, GPIO_FUNC_SIO);
+ gpio_set_dir(sda->number, GPIO_IN);
+ gpio_set_dir(scl->number, GPIO_IN);
+
+ gpio_set_pulls(sda->number, false, true);
+ gpio_set_pulls(scl->number, false, true);
+
+ common_hal_mcu_delay_us(10);
+
+ gpio_set_pulls(sda->number, false, false);
+ gpio_set_pulls(scl->number, false, false);
+
+ // We must pull up within 3us to achieve 400khz.
+ common_hal_mcu_delay_us(3);
+
+ if (!gpio_get(sda->number) || !gpio_get(scl->number)) {
+ reset_pin_number(sda->number);
+ reset_pin_number(scl->number);
+ mp_raise_RuntimeError(translate("SDA or SCL needs a pull up"));
+ }
+#endif
+
+ gpio_set_function(sda->number, GPIO_FUNC_I2C);
+ gpio_set_function(scl->number, GPIO_FUNC_I2C);
+
+ self->baudrate = i2c_init(self->peripheral, frequency);
+
+ self->sda_pin = sda->number;
+ self->scl_pin = scl->number;
+ claim_pin(sda);
+ claim_pin(scl);
+}
+
+bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
+ return self->sda_pin == NO_PIN;
+}
+
+void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
+ if (common_hal_busio_i2c_deinited(self)) {
+ return;
+ }
+ never_reset_i2c[i2c_hw_index(self->peripheral)] = false;
+
+ i2c_deinit(self->peripheral);
+
+ reset_pin_number(self->sda_pin);
+ reset_pin_number(self->scl_pin);
+ self->sda_pin = NO_PIN;
+ self->scl_pin = NO_PIN;
+}
+
+bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
+ uint8_t fake_read = 0;
+ return i2c_read_blocking(self->peripheral, addr, &fake_read, 1, false) != PICO_ERROR_GENERIC;
+}
+
+bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) {
+ bool grabbed_lock = false;
+ if (!self->has_lock) {
+ grabbed_lock = true;
+ self->has_lock = true;
+ }
+ return grabbed_lock;
+}
+
+bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) {
+ return self->has_lock;
+}
+
+void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) {
+ self->has_lock = false;
+}
+
+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) {
+ int result = i2c_write_blocking(self->peripheral, addr, data, len, !transmit_stop_bit);
+ if (result == len) {
+ return 0;
+ } else if (result == PICO_ERROR_GENERIC) {
+ return MP_ENODEV;
+ }
+ return MP_EIO;
+}
+
+uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr,
+ uint8_t *data, size_t len) {
+ int result = i2c_read_blocking(self->peripheral, addr, data, len, false);
+ if (result == len) {
+ return 0;
+ } else if (result == PICO_ERROR_GENERIC) {
+ return MP_ENODEV;
+ }
+ return MP_EIO;
+}
+
+void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) {
+ never_reset_i2c[i2c_hw_index(self->peripheral)] = true;
+
+ never_reset_pin_number(self->scl_pin);
+ never_reset_pin_number(self->sda_pin);
+}
diff --git a/ports/raspberrypi/common-hal/busio/I2C.h b/ports/raspberrypi/common-hal/busio/I2C.h
new file mode 100644
index 000000000..d09f29e54
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/I2C.h
@@ -0,0 +1,47 @@
+/*
+ * 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_COMMON_HAL_BUSIO_I2C_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_I2C_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ i2c_inst_t * peripheral;
+ bool has_lock;
+ uint baudrate;
+ uint8_t scl_pin;
+ uint8_t sda_pin;
+} busio_i2c_obj_t;
+
+void reset_i2c(void);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_I2C_H
diff --git a/ports/raspberrypi/common-hal/busio/OneWire.h b/ports/raspberrypi/common-hal/busio/OneWire.h
new file mode 100644
index 000000000..e27723ab2
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/OneWire.h
@@ -0,0 +1,33 @@
+/*
+ * 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_COMMON_HAL_BUSIO_ONEWIRE_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_ONEWIRE_H
+
+// Use bitbangio.
+#include "shared-module/busio/OneWire.h"
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_ONEWIRE_H
diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c
new file mode 100644
index 000000000..b157ae3eb
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/SPI.c
@@ -0,0 +1,294 @@
+/*
+ * 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 "shared-bindings/busio/SPI.h"
+
+#include "lib/utils/interrupt_char.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+
+#include "supervisor/board.h"
+#include "common-hal/microcontroller/Pin.h"
+#include "supervisor/shared/rgb_led_status.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+#include "src/rp2_common/hardware_dma/include/hardware/dma.h"
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+
+#define NO_INSTANCE 0xff
+
+STATIC bool never_reset_spi[2];
+STATIC spi_inst_t* spi[2] = {spi0, spi1};
+
+void reset_spi(void) {
+ for (size_t i = 0; i < 2; i++) {
+ if (never_reset_spi[i]) {
+ continue;
+ }
+
+ spi_deinit(spi[i]);
+ }
+}
+
+void common_hal_busio_spi_construct(busio_spi_obj_t *self,
+ const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
+ const mcu_pin_obj_t * miso) {
+ size_t instance_index = NO_INSTANCE;
+ if (clock->number % 4 == 2) {
+ instance_index = (clock->number / 8) % 2;
+ }
+ if (mosi != NULL) {
+ // Make sure the set MOSI matches the clock settings.
+ if (mosi->number % 4 != 3 ||
+ (mosi->number / 8) % 2 != instance_index) {
+ instance_index = NO_INSTANCE;
+ }
+ }
+ if (miso != NULL) {
+ // Make sure the set MOSI matches the clock settings.
+ if (miso->number % 4 != 0 ||
+ (miso->number / 8) % 2 != instance_index) {
+ instance_index = NO_INSTANCE;
+ }
+ }
+
+ // TODO: Check to see if we're sharing the SPI with a native APA102.
+
+ if (instance_index > 1) {
+ mp_raise_ValueError(translate("Invalid pins"));
+ }
+
+ if (instance_index == 0) {
+ self->peripheral = spi0;
+ } else if (instance_index == 1) {
+ self->peripheral = spi1;
+ }
+
+ if ((spi_get_hw(self->peripheral)->cr1 & SPI_SSPCR1_SSE_BITS) != 0) {
+ mp_raise_ValueError(translate("SPI peripheral in use"));
+ }
+
+ spi_init(self->peripheral, 250000);
+
+ gpio_set_function(clock->number, GPIO_FUNC_SPI);
+ claim_pin(clock);
+ self->clock = clock;
+
+ self->MOSI = mosi;
+ if (mosi != NULL) {
+ gpio_set_function(mosi->number, GPIO_FUNC_SPI);
+ claim_pin(mosi);
+ }
+
+ self->MISO = miso;
+ if (miso != NULL) {
+ gpio_set_function(miso->number, GPIO_FUNC_SPI);
+ claim_pin(miso);
+ }
+}
+
+void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
+ never_reset_spi[spi_get_index(self->peripheral)] = true;
+
+ common_hal_never_reset_pin(self->clock);
+ common_hal_never_reset_pin(self->MOSI);
+ common_hal_never_reset_pin(self->MISO);
+}
+
+bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
+ return self->clock == NULL;
+}
+
+void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
+ if (common_hal_busio_spi_deinited(self)) {
+ return;
+ }
+ never_reset_spi[spi_get_index(self->peripheral)] = false;
+ spi_deinit(self->peripheral);
+
+ common_hal_reset_pin(self->clock);
+ common_hal_reset_pin(self->MOSI);
+ common_hal_reset_pin(self->MISO);
+ self->clock = NULL;
+}
+
+bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
+ uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
+ if (baudrate == self->target_frequency &&
+ polarity == self->polarity &&
+ phase == self->phase &&
+ bits == self->bits) {
+ return true;
+ }
+
+ spi_set_format(self->peripheral, bits, polarity, phase, SPI_MSB_FIRST);
+
+ self->polarity = polarity;
+ self->phase = phase;
+ self->bits = bits;
+ self->target_frequency = baudrate;
+ self->real_frequency = spi_set_baudrate(self->peripheral, baudrate);
+
+ return true;
+}
+
+bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) {
+ bool grabbed_lock = false;
+ if (!self->has_lock) {
+ grabbed_lock = true;
+ self->has_lock = true;
+ }
+ return grabbed_lock;
+}
+
+bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) {
+ return self->has_lock;
+}
+
+void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
+ self->has_lock = false;
+}
+
+static bool _transfer(busio_spi_obj_t *self,
+ const uint8_t *data_out, size_t out_len,
+ uint8_t *data_in, size_t in_len) {
+ // Use DMA for large transfers if channels are available
+ const size_t dma_min_size_threshold = 32;
+ int chan_tx = -1;
+ int chan_rx = -1;
+ size_t len = MAX(out_len, in_len);
+ if (len >= dma_min_size_threshold) {
+ // Use two DMA channels to service the two FIFOs
+ chan_tx = dma_claim_unused_channel(false);
+ chan_rx = dma_claim_unused_channel(false);
+ }
+ bool use_dma = chan_rx >= 0 && chan_tx >= 0;
+ if (use_dma) {
+ dma_channel_config c = dma_channel_get_default_config(chan_tx);
+ channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
+ channel_config_set_dreq(&c, spi_get_index(self->peripheral) ? DREQ_SPI1_TX : DREQ_SPI0_TX);
+ channel_config_set_read_increment(&c, out_len == len);
+ channel_config_set_write_increment(&c, false);
+ dma_channel_configure(chan_tx, &c,
+ &spi_get_hw(self->peripheral)->dr,
+ data_out,
+ len,
+ false);
+
+ c = dma_channel_get_default_config(chan_rx);
+ channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
+ channel_config_set_dreq(&c, spi_get_index(self->peripheral) ? DREQ_SPI1_RX : DREQ_SPI0_RX);
+ channel_config_set_read_increment(&c, false);
+ channel_config_set_write_increment(&c, in_len == len);
+ dma_channel_configure(chan_rx, &c,
+ data_in,
+ &spi_get_hw(self->peripheral)->dr,
+ len,
+ false);
+
+ dma_start_channel_mask((1u << chan_rx) | (1u << chan_tx));
+ while (dma_channel_is_busy(chan_rx) || dma_channel_is_busy(chan_tx)) {
+ // TODO: We should idle here until we get a DMA interrupt or something else.
+ RUN_BACKGROUND_TASKS;
+ if (mp_hal_is_interrupted()) {
+ if (dma_channel_is_busy(chan_rx)) {
+ dma_channel_abort(chan_rx);
+ }
+ if (dma_channel_is_busy(chan_tx)) {
+ dma_channel_abort(chan_tx);
+ }
+ break;
+ }
+ }
+ }
+
+ // If we have claimed only one channel successfully, we should release immediately. This also
+ // releases the DMA after use_dma has been done.
+ if (chan_rx >= 0) {
+ dma_channel_unclaim(chan_rx);
+ }
+ if (chan_tx >= 0) {
+ dma_channel_unclaim(chan_tx);
+ }
+
+ if (!use_dma && !mp_hal_is_interrupted()) {
+ // Use software for small transfers, or if couldn't claim two DMA channels
+ // Never have more transfers in flight than will fit into the RX FIFO,
+ // else FIFO will overflow if this code is heavily interrupted.
+ const size_t fifo_depth = 8;
+ size_t rx_remaining = len;
+ size_t tx_remaining = len;
+
+ while (!mp_hal_is_interrupted() && (rx_remaining || tx_remaining)) {
+ if (tx_remaining && spi_is_writable(self->peripheral) && rx_remaining - tx_remaining < fifo_depth) {
+ spi_get_hw(self->peripheral)->dr = (uint32_t) *data_out;
+ // Increment only if the buffer is the transfer length. It's 1 otherwise.
+ if (out_len == len) {
+ data_out++;
+ }
+ --tx_remaining;
+ }
+ if (rx_remaining && spi_is_readable(self->peripheral)) {
+ *data_in = (uint8_t) spi_get_hw(self->peripheral)->dr;
+ // Increment only if the buffer is the transfer length. It's 1 otherwise.
+ if (in_len == len) {
+ data_in++;
+ }
+ --rx_remaining;
+ }
+ RUN_BACKGROUND_TASKS;
+ }
+ }
+ return true;
+}
+
+bool common_hal_busio_spi_write(busio_spi_obj_t *self,
+ const uint8_t *data, size_t len) {
+ uint32_t data_in;
+ return _transfer(self, data, len, (uint8_t*) &data_in, MIN(len, 4));
+}
+
+bool common_hal_busio_spi_read(busio_spi_obj_t *self,
+ uint8_t *data, size_t len, uint8_t write_value) {
+ uint32_t data_out = write_value << 24 | write_value << 16 | write_value << 8 | write_value;
+ return _transfer(self, (const uint8_t*) &data_out, MIN(4, len), data, len);
+}
+
+bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) {
+ return _transfer(self, data_out, len, data_in, len);
+}
+
+uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
+ return self->real_frequency;
+}
+
+uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self) {
+ return self->phase;
+}
+
+uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self) {
+ return self->polarity;
+}
diff --git a/ports/raspberrypi/common-hal/busio/SPI.h b/ports/raspberrypi/common-hal/busio/SPI.h
new file mode 100644
index 000000000..981db46d4
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/SPI.h
@@ -0,0 +1,52 @@
+/*
+ * 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_COMMON_HAL_BUSIO_SPI_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_SPI_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+#include "src/rp2_common/hardware_spi/include/hardware/spi.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ spi_inst_t * peripheral;
+ bool has_lock;
+ const mcu_pin_obj_t* clock;
+ const mcu_pin_obj_t* MOSI;
+ const mcu_pin_obj_t* MISO;
+ uint32_t target_frequency;
+ int32_t real_frequency;
+ uint8_t polarity;
+ uint8_t phase;
+ uint8_t bits;
+} busio_spi_obj_t;
+
+void reset_spi(void);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_SPI_H
diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c
new file mode 100644
index 000000000..f9a75b499
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/UART.c
@@ -0,0 +1,404 @@
+/*
+ * 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 "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/busio/UART.h"
+
+#include "mpconfigport.h"
+#include "lib/utils/interrupt_char.h"
+#include "py/gc.h"
+#include "py/mperrno.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
+
+#define UART_DEBUG(...) (void)0
+// #define UART_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
+
+// Do-nothing callback needed so that usart_async code will enable rx interrupts.
+// See comment below re usart_async_register_callback()
+// static void usart_async_rxc_callback(const struct usart_async_descriptor *const descr) {
+// // Nothing needs to be done by us.
+// }
+
+#define NO_PIN 0xff
+
+void common_hal_busio_uart_construct(busio_uart_obj_t *self,
+ const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
+ const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
+ const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
+ uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop,
+ mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
+ bool sigint_enabled) {
+ mp_raise_NotImplementedError(translate("UART not yet supported"));
+
+// Sercom* sercom = NULL;
+// uint8_t sercom_index = 255; // Unset index
+// uint32_t rx_pinmux = 0;
+// uint8_t rx_pad = 255; // Unset pad
+// uint32_t tx_pinmux = 0;
+// uint8_t tx_pad = 255; // Unset pad
+
+// if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
+// mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+// }
+
+// if (bits > 8) {
+// mp_raise_NotImplementedError(translate("bytes > 8 bits not supported"));
+// }
+
+// bool have_tx = tx != NULL;
+// bool have_rx = rx != NULL;
+// if (!have_tx && !have_rx) {
+// mp_raise_ValueError(translate("tx and rx cannot both be None"));
+// }
+
+// self->baudrate = baudrate;
+// self->character_bits = bits;
+// self->timeout_ms = timeout * 1000;
+
+// // This assignment is only here because the usart_async routines take a *const argument.
+// struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+
+// for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) {
+// Sercom* potential_sercom = NULL;
+// if (have_tx) {
+// sercom_index = tx->sercom[i].index;
+// if (sercom_index >= SERCOM_INST_NUM) {
+// continue;
+// }
+// potential_sercom = sercom_insts[sercom_index];
+// #ifdef SAMD21
+// if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
+// !(tx->sercom[i].pad == 0 ||
+// tx->sercom[i].pad == 2)) {
+// continue;
+// }
+// #endif
+// #ifdef SAM_D5X_E5X
+// if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 ||
+// !(tx->sercom[i].pad == 0)) {
+// continue;
+// }
+// #endif
+// tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D);
+// tx_pad = tx->sercom[i].pad;
+// if (rx == NULL) {
+// sercom = potential_sercom;
+// break;
+// }
+// }
+// for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) {
+// if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM &&
+// sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) ||
+// sercom_index == rx->sercom[j].index) &&
+// rx->sercom[j].pad != tx_pad) {
+// rx_pinmux = PINMUX(rx->number, (j == 0) ? MUX_C : MUX_D);
+// rx_pad = rx->sercom[j].pad;
+// sercom = sercom_insts[rx->sercom[j].index];
+// sercom_index = rx->sercom[j].index;
+// break;
+// }
+// }
+// if (sercom != NULL) {
+// break;
+// }
+// }
+// if (sercom == NULL) {
+// mp_raise_ValueError(translate("Invalid pins"));
+// }
+// if (!have_tx) {
+// tx_pad = 0;
+// if (rx_pad == 0) {
+// tx_pad = 2;
+// }
+// }
+// if (!have_rx) {
+// rx_pad = (tx_pad + 1) % 4;
+// }
+
+// // Set up clocks on SERCOM.
+// samd_peripherals_sercom_clock_init(sercom, sercom_index);
+
+// if (rx && receiver_buffer_size > 0) {
+// self->buffer_length = receiver_buffer_size;
+// // Initially allocate the UART's buffer in the long-lived part of the
+// // heap. UARTs are generally long-lived objects, but the "make long-
+// // lived" machinery is incapable of moving internal pointers like
+// // self->buffer, so do it manually. (However, as long as internal
+// // pointers like this are NOT moved, allocating the buffer
+// // in the long-lived pool is not strictly necessary)
+// self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, true);
+// if (self->buffer == NULL) {
+// common_hal_busio_uart_deinit(self);
+// mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), self->buffer_length * sizeof(uint8_t));
+// }
+// } else {
+// self->buffer_length = 0;
+// self->buffer = NULL;
+// }
+
+// if (usart_async_init(usart_desc_p, sercom, self->buffer, self->buffer_length, NULL) != ERR_NONE) {
+// mp_raise_ValueError(translate("Could not initialize UART"));
+// }
+
+// // usart_async_init() sets a number of defaults based on a prototypical SERCOM
+// // which don't necessarily match what we need. After calling it, set the values
+// // specific to this instantiation of UART.
+
+// // Set pads computed for this SERCOM.
+// // TXPO:
+// // 0x0: TX pad 0; no RTS/CTS
+// // 0x1: TX pad 2; no RTS/CTS
+// // 0x2: TX pad 0; RTS: pad 2, CTS: pad 3 (not used by us right now)
+// // So divide by 2 to map pad to value.
+// // RXPO:
+// // 0x0: RX pad 0
+// // 0x1: RX pad 1
+// // 0x2: RX pad 2
+// // 0x3: RX pad 3
+
+// // Doing a group mask and set of the registers saves 60 bytes over setting the bitfields individually.
+
+// sercom->USART.CTRLA.reg &= ~(SERCOM_USART_CTRLA_TXPO_Msk |
+// SERCOM_USART_CTRLA_RXPO_Msk |
+// SERCOM_USART_CTRLA_FORM_Msk);
+// sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(tx_pad / 2) |
+// SERCOM_USART_CTRLA_RXPO(rx_pad) |
+// (parity == BUSIO_UART_PARITY_NONE ? 0 : SERCOM_USART_CTRLA_FORM(1));
+
+// // Enable tx and/or rx based on whether the pins were specified.
+// // CHSIZE is 0 for 8 bits, 5, 6, 7 for 5, 6, 7 bits. 1 for 9 bits, but we don't support that.
+// sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_TXEN |
+// SERCOM_USART_CTRLB_RXEN |
+// SERCOM_USART_CTRLB_PMODE |
+// SERCOM_USART_CTRLB_SBMODE |
+// SERCOM_USART_CTRLB_CHSIZE_Msk);
+// sercom->USART.CTRLB.reg |= (have_tx ? SERCOM_USART_CTRLB_TXEN : 0) |
+// (have_rx ? SERCOM_USART_CTRLB_RXEN : 0) |
+// (parity == BUSIO_UART_PARITY_ODD ? SERCOM_USART_CTRLB_PMODE : 0) |
+// (stop > 1 ? SERCOM_USART_CTRLB_SBMODE : 0) |
+// SERCOM_USART_CTRLB_CHSIZE(bits % 8);
+
+// // Set baud rate
+// common_hal_busio_uart_set_baudrate(self, baudrate);
+
+// // Turn on rx interrupt handling. The UART async driver has its own set of internal callbacks,
+// // which are set up by uart_async_init(). These in turn can call user-specified callbacks.
+// // In fact, the actual interrupts are not enabled unless we set up a user-specified callback.
+// // This is confusing. It's explained in the Atmel START User Guide -> Implementation Description ->
+// // Different read function behavior in some asynchronous drivers. As of this writing:
+// // http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836
+// // Look at the ASFv4 code example for async USART.
+// usart_async_register_callback(usart_desc_p, USART_ASYNC_RXC_CB, usart_async_rxc_callback);
+
+
+// if (have_tx) {
+// gpio_set_pin_direction(tx->number, GPIO_DIRECTION_OUT);
+// gpio_set_pin_pull_mode(tx->number, GPIO_PULL_OFF);
+// gpio_set_pin_function(tx->number, tx_pinmux);
+// self->tx_pin = tx->number;
+// claim_pin(tx);
+// } else {
+// self->tx_pin = NO_PIN;
+// }
+
+// if (have_rx) {
+// gpio_set_pin_direction(rx->number, GPIO_DIRECTION_IN);
+// gpio_set_pin_pull_mode(rx->number, GPIO_PULL_OFF);
+// gpio_set_pin_function(rx->number, rx_pinmux);
+// self->rx_pin = rx->number;
+// claim_pin(rx);
+// } else {
+// self->rx_pin = NO_PIN;
+// }
+
+// usart_async_enable(usart_desc_p);
+}
+
+bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
+ return self->rx_pin == NO_PIN && self->tx_pin == NO_PIN;
+}
+
+void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
+ if (common_hal_busio_uart_deinited(self)) {
+ return;
+ }
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ // usart_async_disable(usart_desc_p);
+ // usart_async_deinit(usart_desc_p);
+ reset_pin_number(self->rx_pin);
+ reset_pin_number(self->tx_pin);
+ self->rx_pin = NO_PIN;
+ self->tx_pin = NO_PIN;
+}
+
+// Read characters.
+size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
+ if (self->rx_pin == NO_PIN) {
+ mp_raise_ValueError(translate("No RX pin"));
+ }
+
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+
+ if (len == 0) {
+ // Nothing to read.
+ return 0;
+ }
+
+ // struct io_descriptor *io;
+ // usart_async_get_io_descriptor(usart_desc_p, &io);
+
+ size_t total_read = 0;
+ // uint64_t start_ticks = supervisor_ticks_ms64();
+
+ // // Busy-wait until timeout or until we've read enough chars.
+ // while (supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) {
+ // // Read as many chars as we can right now, up to len.
+ // size_t num_read = io_read(io, data, len);
+
+ // // Advance pointer in data buffer, and decrease how many chars left to read.
+ // data += num_read;
+ // len -= num_read;
+ // total_read += num_read;
+ // if (len == 0) {
+ // // Don't need to read any more: data buf is full.
+ // break;
+ // }
+ // if (num_read > 0) {
+ // // Reset the timeout on every character read.
+ // start_ticks = supervisor_ticks_ms64();
+ // }
+ // RUN_BACKGROUND_TASKS;
+ // // Allow user to break out of a timeout with a KeyboardInterrupt.
+ // if (mp_hal_is_interrupted()) {
+ // break;
+ // }
+ // // If we are zero timeout, make sure we don't loop again (in the event
+ // // we read in under 1ms)
+ // if (self->timeout_ms == 0) {
+ // break;
+ // }
+ // }
+
+ // if (total_read == 0) {
+ // *errcode = EAGAIN;
+ // return MP_STREAM_ERROR;
+ // }
+
+ return total_read;
+}
+
+// Write characters.
+size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
+ if (self->tx_pin == NO_PIN) {
+ mp_raise_ValueError(translate("No TX pin"));
+ }
+
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+
+ // struct io_descriptor *io;
+ // usart_async_get_io_descriptor(usart_desc_p, &io);
+
+ // // Start writing characters. This is non-blocking and will
+ // // return immediately after setting up the write.
+ // if (io_write(io, data, len) < 0) {
+ // *errcode = MP_EAGAIN;
+ // return MP_STREAM_ERROR;
+ // }
+
+ // // Busy-wait until all characters transmitted.
+ // struct usart_async_status async_status;
+ // while (true) {
+ // usart_async_get_status(usart_desc_p, &async_status);
+ // if (async_status.txcnt >= len) {
+ // break;
+ // }
+ // RUN_BACKGROUND_TASKS;
+ // }
+
+ return len;
+}
+
+uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {
+ return self->baudrate;
+}
+
+void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) {
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ // usart_async_set_baud_rate(usart_desc_p,
+ // // Samples and ARITHMETIC vs FRACTIONAL must correspond to USART_SAMPR in
+ // // hpl_sercom_config.h.
+ // _usart_async_calculate_baud_rate(baudrate, // e.g. 9600 baud
+ // PROTOTYPE_SERCOM_USART_ASYNC_CLOCK_FREQUENCY,
+ // 16, // samples
+ // USART_BAUDRATE_ASYNCH_ARITHMETIC,
+ // 0 // fraction - not used for ARITHMETIC
+ // ));
+ self->baudrate = baudrate;
+}
+
+mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) {
+ return (mp_float_t) (self->timeout_ms / 1000.0f);
+}
+
+void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) {
+ self->timeout_ms = timeout * 1000;
+}
+
+uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ // struct usart_async_status async_status;
+ // usart_async_get_status(usart_desc_p, &async_status);
+ // return async_status.rxcnt;
+ return 0;
+}
+
+void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
+ // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ // usart_async_flush_rx_buffer(usart_desc_p);
+
+}
+
+// True if there are no characters still to be written.
+bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
+ if (self->tx_pin == NO_PIN) {
+ return false;
+ }
+ return false;
+ // // This assignment is only here because the usart_async routines take a *const argument.
+ // struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc;
+ // struct usart_async_status async_status;
+ // usart_async_get_status(usart_desc_p, &async_status);
+ // return !(async_status.flags & USART_ASYNC_STATUS_BUSY);
+}
diff --git a/ports/raspberrypi/common-hal/busio/UART.h b/ports/raspberrypi/common-hal/busio/UART.h
new file mode 100644
index 000000000..43ed9bee0
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/UART.h
@@ -0,0 +1,47 @@
+/*
+ * 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_COMMON_HAL_BUSIO_UART_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_UART_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // struct usart_async_descriptor usart_desc;
+ uint8_t rx_pin;
+ uint8_t tx_pin;
+ uint8_t character_bits;
+ bool rx_error;
+ uint32_t baudrate;
+ uint32_t timeout_ms;
+ uint32_t buffer_length;
+ uint8_t* buffer;
+} busio_uart_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_UART_H
diff --git a/ports/raspberrypi/common-hal/busio/__init__.c b/ports/raspberrypi/common-hal/busio/__init__.c
new file mode 100644
index 000000000..41761b674
--- /dev/null
+++ b/ports/raspberrypi/common-hal/busio/__init__.c
@@ -0,0 +1 @@
+// No busio module functions.
diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c
new file mode 100644
index 000000000..b0bc1b96e
--- /dev/null
+++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c
@@ -0,0 +1,154 @@
+/*
+ * 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 <stdint.h>
+#include <string.h>
+
+#include "py/runtime.h"
+#include "py/mphal.h"
+
+#include "common-hal/microcontroller/Pin.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "supervisor/shared/translate.h"
+
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+
+digitalinout_result_t common_hal_digitalio_digitalinout_construct(
+ digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) {
+ claim_pin(pin);
+ self->pin = pin;
+ self->output = false;
+ self->open_drain = false;
+
+ gpio_init(pin->number);
+ return DIGITALINOUT_OK;
+}
+
+void common_hal_digitalio_digitalinout_never_reset(
+ digitalio_digitalinout_obj_t *self) {
+ never_reset_pin_number(self->pin->number);
+}
+
+bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) {
+ return self->pin == NULL;
+}
+
+void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) {
+ if (common_hal_digitalio_digitalinout_deinited(self)) {
+ return;
+ }
+ reset_pin_number(self->pin->number);
+ self->pin = NULL;
+}
+
+void common_hal_digitalio_digitalinout_switch_to_input(
+ digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
+ self->output = false;
+ // This also sets direction to input.
+ common_hal_digitalio_digitalinout_set_pull(self, pull);
+}
+
+digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output(
+ digitalio_digitalinout_obj_t* self, bool value,
+ digitalio_drive_mode_t drive_mode) {
+ const uint8_t pin = self->pin->number;
+ gpio_set_dir(pin, GPIO_OUT);
+ // TODO: Turn on "strong" pin driving (more current available).
+
+ self->output = true;
+ common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode);
+ common_hal_digitalio_digitalinout_set_value(self, value);
+ return DIGITALINOUT_OK;
+}
+
+digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
+ digitalio_digitalinout_obj_t* self) {
+ return self->output ? DIRECTION_OUTPUT : DIRECTION_INPUT;
+}
+
+void common_hal_digitalio_digitalinout_set_value(
+ digitalio_digitalinout_obj_t* self, bool value) {
+ const uint8_t pin = self->pin->number;
+ if (self->open_drain) {
+ gpio_set_dir(pin, value ? GPIO_IN : GPIO_OUT);
+ } else {
+ gpio_put(pin, value);
+ }
+}
+
+bool common_hal_digitalio_digitalinout_get_value(
+ digitalio_digitalinout_obj_t* self) {
+ return gpio_get(self->pin->number);
+}
+
+digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode(
+ digitalio_digitalinout_obj_t* self,
+ digitalio_drive_mode_t drive_mode) {
+ const uint8_t pin = self->pin->number;
+ bool value = common_hal_digitalio_digitalinout_get_value(self);
+ self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
+ if (self->open_drain) {
+ gpio_put(pin, false);
+ }
+ // True is implemented differently between modes so reset the value to make
+ // sure it's correct for the new mode.
+ if (value) {
+ common_hal_digitalio_digitalinout_set_value(self, value);
+ }
+ return DIGITALINOUT_OK;
+}
+
+digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(
+ digitalio_digitalinout_obj_t* self) {
+ if (self->open_drain) {
+ return DRIVE_MODE_OPEN_DRAIN;
+ } else {
+ return DRIVE_MODE_PUSH_PULL;
+ }
+}
+
+void common_hal_digitalio_digitalinout_set_pull(
+ digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
+ const uint8_t pin = self->pin->number;
+ gpio_set_pulls(pin, pull == PULL_UP, pull == PULL_DOWN);
+ gpio_set_dir(pin, GPIO_IN);
+}
+
+digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
+ digitalio_digitalinout_obj_t* self) {
+ uint32_t pin = self->pin->number;
+ if (self->output) {
+ mp_raise_AttributeError(translate("Cannot get pull while in output mode"));
+ return PULL_NONE;
+ } else {
+ if (gpio_is_pulled_up(pin)) {
+ return PULL_UP;
+ } else if (gpio_is_pulled_down(pin)) {
+ return PULL_DOWN;
+ }
+ }
+ return PULL_NONE;
+}
diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.h b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.h
new file mode 100644
index 000000000..8b14bbad8
--- /dev/null
+++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
+
+#include "common-hal/microcontroller/Pin.h"
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ const mcu_pin_obj_t * pin;
+ bool output;
+ bool open_drain;
+} digitalio_digitalinout_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
diff --git a/ports/raspberrypi/common-hal/digitalio/__init__.c b/ports/raspberrypi/common-hal/digitalio/__init__.c
new file mode 100644
index 000000000..20fad4595
--- /dev/null
+++ b/ports/raspberrypi/common-hal/digitalio/__init__.c
@@ -0,0 +1 @@
+// No digitalio module functions.
diff --git a/ports/raspberrypi/common-hal/displayio/ParallelBus.c b/ports/raspberrypi/common-hal/displayio/ParallelBus.c
new file mode 100644
index 000000000..57b2ffc36
--- /dev/null
+++ b/ports/raspberrypi/common-hal/displayio/ParallelBus.c
@@ -0,0 +1,68 @@
+/*
+ * 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 "shared-bindings/displayio/ParallelBus.h"
+
+#include <stdint.h>
+
+#include "common-hal/microcontroller/Pin.h"
+#include "py/runtime.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self,
+ const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select,
+ const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) {
+
+ mp_raise_NotImplementedError(translate("ParallelBus not yet supported"));
+ // TODO: Implement with PIO and DMA.
+}
+
+void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) {
+
+}
+
+bool common_hal_displayio_parallelbus_reset(mp_obj_t obj) {
+ return false;
+}
+
+bool common_hal_displayio_parallelbus_bus_free(mp_obj_t obj) {
+ return false;
+}
+
+bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) {
+
+ return false;
+}
+
+void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type,
+ display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) {
+
+}
+
+void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) {
+
+}
diff --git a/ports/raspberrypi/common-hal/displayio/ParallelBus.h b/ports/raspberrypi/common-hal/displayio/ParallelBus.h
new file mode 100644
index 000000000..45989d990
--- /dev/null
+++ b/ports/raspberrypi/common-hal/displayio/ParallelBus.h
@@ -0,0 +1,36 @@
+/*
+ * 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_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
+
+#include "common-hal/digitalio/DigitalInOut.h"
+
+typedef struct {
+ mp_obj_base_t base;
+} displayio_parallelbus_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_DISPLAYIO_PARALLELBUS_H
diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.c b/ports/raspberrypi/common-hal/microcontroller/Pin.c
new file mode 100644
index 000000000..ca5cf5a04
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/Pin.c
@@ -0,0 +1,181 @@
+/*
+ * 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 "py/runtime.h"
+
+#include "common-hal/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+#include "supervisor/shared/rgb_led_status.h"
+
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+
+#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
+#ifdef SPEAKER_ENABLE_PIN
+bool speaker_enable_in_use;
+#endif
+
+STATIC uint32_t never_reset_pins;
+
+void reset_all_pins(void) {
+ for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
+ if ((never_reset_pins & (1 << i)) != 0) {
+ continue;
+ }
+ reset_pin_number(i);
+ }
+}
+
+void never_reset_pin_number(uint8_t pin_number) {
+ if (pin_number >= TOTAL_GPIO_COUNT) {
+ return;
+ }
+
+ never_reset_pins |= 1 << pin_number;
+}
+
+void reset_pin_number(uint8_t pin_number) {
+ if (pin_number >= TOTAL_GPIO_COUNT) {
+ return;
+ }
+
+ never_reset_pins &= ~(1 << pin_number);
+
+ // We are very aggressive in shutting down the pad fully. Both pulls are
+ // disabled and both buffers are as well.
+ gpio_init(pin_number);
+ hw_clear_bits(&padsbank0_hw->io[pin_number], PADS_BANK0_GPIO0_IE_BITS |
+ PADS_BANK0_GPIO0_PUE_BITS |
+ PADS_BANK0_GPIO0_PDE_BITS);
+ hw_set_bits(&padsbank0_hw->io[pin_number], PADS_BANK0_GPIO0_OD_BITS);
+
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin_number == MICROPY_HW_NEOPIXEL->number) {
+ neopixel_in_use = false;
+ rgb_led_status_init();
+ 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
+
+ #ifdef SPEAKER_ENABLE_PIN
+ if (pin_number == SPEAKER_ENABLE_PIN->number) {
+ speaker_enable_in_use = false;
+ }
+ #endif
+}
+
+void common_hal_never_reset_pin(const mcu_pin_obj_t* pin) {
+ never_reset_pin_number(pin->number);
+}
+
+void common_hal_reset_pin(const mcu_pin_obj_t* pin) {
+ reset_pin_number(pin->number);
+}
+
+void claim_pin(const mcu_pin_obj_t* pin) {
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin == MICROPY_HW_NEOPIXEL) {
+ 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
+
+ #ifdef SPEAKER_ENABLE_PIN
+ if (pin == SPEAKER_ENABLE_PIN) {
+ speaker_enable_in_use = true;
+ }
+ #endif
+}
+
+bool pin_number_is_free(uint8_t pin_number) {
+ if (pin_number >= TOTAL_GPIO_COUNT) {
+ return false;
+ }
+
+ uint32_t pad_state = padsbank0_hw->io[pin_number];
+ return (pad_state & PADS_BANK0_GPIO0_IE_BITS) == 0 &&
+ (pad_state & PADS_BANK0_GPIO0_OD_BITS) != 0;
+}
+
+bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
+ #ifdef MICROPY_HW_NEOPIXEL
+ if (pin == MICROPY_HW_NEOPIXEL) {
+ return !neopixel_in_use;
+ }
+ #endif
+ #ifdef MICROPY_HW_APA102_MOSI
+ if (pin == MICROPY_HW_APA102_MOSI) {
+ return !apa102_mosi_in_use;
+ }
+ if (pin == MICROPY_HW_APA102_SCK) {
+ return !apa102_sck_in_use;
+ }
+ #endif
+
+ #ifdef SPEAKER_ENABLE_PIN
+ if (pin == SPEAKER_ENABLE_PIN) {
+ return !speaker_enable_in_use;
+ }
+ #endif
+
+ return pin_number_is_free(pin->number);
+}
+
+uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) {
+ return pin->number;
+}
+
+void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) {
+ return claim_pin(pin);
+}
+
+void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
+ reset_pin_number(pin_no);
+}
diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.h b/ports/raspberrypi/common-hal/microcontroller/Pin.h
new file mode 100644
index 000000000..07c321185
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/Pin.h
@@ -0,0 +1,53 @@
+/*
+ * 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_COMMON_HAL_MICROCONTROLLER_PIN_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PIN_H
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <py/obj.h>
+
+#include "peripherals/pins.h"
+
+#ifdef MICROPY_HW_NEOPIXEL
+extern bool neopixel_in_use;
+#endif
+#ifdef MICROPY_HW_APA102_MOSI
+extern bool apa102_sck_in_use;
+extern bool apa102_mosi_in_use;
+#endif
+
+void reset_all_pins(void);
+// reset_pin_number takes the pin number instead of the pointer so that objects don't
+// need to store a full pointer.
+void reset_pin_number(uint8_t pin_number);
+void never_reset_pin_number(uint8_t pin_number);
+void claim_pin(const mcu_pin_obj_t* pin);
+bool pin_number_is_free(uint8_t pin_number);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PIN_H
diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c
new file mode 100644
index 000000000..0ad3a51e2
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c
@@ -0,0 +1,66 @@
+/*
+ * 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 <math.h>
+
+#include "py/mphal.h"
+#include "common-hal/microcontroller/Processor.h"
+#include "shared-bindings/microcontroller/ResetReason.h"
+
+#include "src/rp2_common/hardware_adc/include/hardware/adc.h"
+#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h"
+
+float common_hal_mcu_processor_get_temperature(void) {
+ adc_init();
+ adc_set_temp_sensor_enabled(true);
+ adc_select_input(4);
+ uint16_t value = adc_read();
+ adc_set_temp_sensor_enabled(false);
+ float voltage = value * 3.3 / (1 << 12);
+ // TODO: turn the ADC back off
+ return 27 - (voltage - 0.706) / 0.001721;
+}
+
+float common_hal_mcu_processor_get_voltage(void) {
+ return 3.3f;
+}
+
+uint32_t common_hal_mcu_processor_get_frequency(void) {
+ return clock_get_hz(clk_sys);
+}
+
+void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
+ // TODO: get the unique id from the flash. The chip itself doesn't have one.
+ // for (int i=0; i<4; i++) {
+ // for (int k=0; k<4; k++) {
+ // raw_id[4 * i + k] = (*(id_addresses[i]) >> k * 8) & 0xff;
+ // }
+ // }
+}
+
+mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
+ return RESET_REASON_UNKNOWN;
+}
diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.h b/ports/raspberrypi/common-hal/microcontroller/Processor.h
new file mode 100644
index 000000000..b7c86e850
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/Processor.h
@@ -0,0 +1,39 @@
+/*
+ * 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_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
+
+#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 16
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Stores no state currently.
+} mcu_processor_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c
new file mode 100644
index 000000000..e454ffa1b
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c
@@ -0,0 +1,148 @@
+/*
+ * 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 "py/mphal.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "common-hal/microcontroller/__init__.h"
+#if CIRCUITPY_NVM
+#include "shared-bindings/nvm/ByteArray.h"
+#endif
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/microcontroller/Processor.h"
+#include "supervisor/shared/safe_mode.h"
+#include "supervisor/shared/translate.h"
+
+#include "src/rp2040/hardware_structs/include/hardware/structs/sio.h"
+#include "src/rp2_common/hardware_sync/include/hardware/sync.h"
+
+void common_hal_mcu_delay_us(uint32_t delay) {
+ mp_hal_delay_us(delay);
+}
+
+volatile uint32_t nesting_count = 0;
+void common_hal_mcu_disable_interrupts(void) {
+ // We don't use save_and_disable_interrupts() from the sdk because we don't want to worry about PRIMASK.
+ // This is what we do on the SAMD21 via CMSIS.
+ asm volatile ("cpsid i" : : : "memory");
+ __dmb();
+ nesting_count++;
+}
+
+void common_hal_mcu_enable_interrupts(void) {
+ if (nesting_count == 0) {
+ // reset_into_safe_mode(LOCKING_ERROR);
+ }
+ nesting_count--;
+ if (nesting_count > 0) {
+ return;
+ }
+ __dmb();
+ asm volatile ("cpsie i" : : : "memory");
+}
+
+void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
+ if (runmode == RUNMODE_BOOTLOADER) {
+ } else {
+ }
+ if (runmode == RUNMODE_SAFE_MODE) {
+ safe_mode_on_next_reset(PROGRAMMATIC_SAFE_MODE);
+ }
+}
+
+void common_hal_mcu_reset(void) {
+}
+
+// The singleton microcontroller.Processor object, bound to microcontroller.cpu
+// It currently only has properties, and no state.
+static const mcu_processor_obj_t processor0 = {
+ .base = {
+ .type = &mcu_processor_type,
+ },
+};
+
+static const mcu_processor_obj_t processor1 = {
+ .base = {
+ .type = &mcu_processor_type,
+ },
+};
+
+const mp_rom_obj_tuple_t common_hal_mcu_processor_obj = {
+ {&mp_type_tuple},
+ CIRCUITPY_PROCESSOR_COUNT,
+ {
+ MP_ROM_PTR(&processor0),
+ MP_ROM_PTR(&processor1)
+ }
+};
+
+#if CIRCUITPY_NVM && CIRCUITPY_INTERNAL_NVM_SIZE > 0
+// The singleton nvm.ByteArray object.
+const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
+ .base = {
+ .type = &nvm_bytearray_type,
+ },
+ .len = CIRCUITPY_INTERNAL_NVM_SIZE,
+ .start_address = (uint8_t*) (CIRCUITPY_INTERNAL_NVM_START_ADDR)
+};
+#endif
+
+// This maps MCU pin names to pin objects.
+const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
+ { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_GPIO5) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO6), MP_ROM_PTR(&pin_GPIO6) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO7), MP_ROM_PTR(&pin_GPIO7) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO8), MP_ROM_PTR(&pin_GPIO8) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO9), MP_ROM_PTR(&pin_GPIO9) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO10), MP_ROM_PTR(&pin_GPIO10) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO11), MP_ROM_PTR(&pin_GPIO11) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO12), MP_ROM_PTR(&pin_GPIO12) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO13), MP_ROM_PTR(&pin_GPIO13) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO14), MP_ROM_PTR(&pin_GPIO14) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO15), MP_ROM_PTR(&pin_GPIO15) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO16), MP_ROM_PTR(&pin_GPIO16) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO17), MP_ROM_PTR(&pin_GPIO17) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO18), MP_ROM_PTR(&pin_GPIO18) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO19), MP_ROM_PTR(&pin_GPIO19) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO20), MP_ROM_PTR(&pin_GPIO20) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO21), MP_ROM_PTR(&pin_GPIO21) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO22), MP_ROM_PTR(&pin_GPIO22) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO23), MP_ROM_PTR(&pin_GPIO23) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO24), MP_ROM_PTR(&pin_GPIO24) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO25), MP_ROM_PTR(&pin_GPIO25) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO26), MP_ROM_PTR(&pin_GPIO26) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO27), MP_ROM_PTR(&pin_GPIO27) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO28), MP_ROM_PTR(&pin_GPIO28) },
+ { MP_ROM_QSTR(MP_QSTR_GPIO29), MP_ROM_PTR(&pin_GPIO29) },
+};
+MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.h b/ports/raspberrypi/common-hal/microcontroller/__init__.h
new file mode 100644
index 000000000..cc509b6b1
--- /dev/null
+++ b/ports/raspberrypi/common-hal/microcontroller/__init__.h
@@ -0,0 +1,36 @@
+/*
+ * 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_COMMON_HAL_MICROCONTROLLER___INIT___H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
+
+#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
+
+#define TOTAL_GPIO_COUNT NUM_BANK0_GPIOS
+
+extern const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT];
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
diff --git a/ports/raspberrypi/common-hal/neopixel_write/__init__.c b/ports/raspberrypi/common-hal/neopixel_write/__init__.c
new file mode 100644
index 000000000..10462b5a3
--- /dev/null
+++ b/ports/raspberrypi/common-hal/neopixel_write/__init__.c
@@ -0,0 +1,95 @@
+/*
+ * 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 "shared-bindings/neopixel_write/__init__.h"
+
+#include "bindings/rp2pio/StateMachine.h"
+#include "common-hal/rp2pio/StateMachine.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+#include "supervisor/port.h"
+
+uint64_t next_start_raw_ticks = 0;
+
+// NeoPixels are 800khz bit streams. Zeroes are 1/3 duty cycle (~416ns) and ones
+// are 2/3 duty cycle (~833ns). Each of the instructions below take 1/3 duty
+// cycle. The first two instructions always run while only one of the two final
+// instructions run per bit. We start with the low period because it can be
+// longer than 1/3 period while waiting for more data.
+const uint16_t neopixel_program[] = {
+// bitloop:
+// out x 1 side 0 [1]; Side-set still takes place before instruction stalls
+ 0x6121,
+// jmp !x do_zero side 1 [1]; Branch on the bit we shifted out after 1/3 duty delay. Positive pulse
+ 0x1123,
+// do_one:
+// jmp bitloop side 1 [1]; Continue driving high, for a long pulse
+ 0x1100,
+// do_zero:
+// nop side 0 [1]; Or drive low, for a short pulse
+ 0xa142
+};
+
+const uint16_t init_program[] = {
+ 0xe081
+};
+
+void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t num_bytes) {
+ // Set everything up.
+ rp2pio_statemachine_obj_t state_machine;
+
+ // TODO: Cache the state machine after we create it once. We'll need a way to
+ // change the pins then though.
+ uint8_t pin_number = digitalinout->pin->number;
+ bool ok = rp2pio_statemachine_construct(&state_machine,
+ neopixel_program, sizeof(neopixel_program) / sizeof(neopixel_program[0]),
+ 800000 * 6, // 800 khz * 6 cycles per bit
+ init_program, 1,
+ NULL, 1,
+ NULL, 1,
+ digitalinout->pin, 1,
+ digitalinout->pin, 1,
+ 1 << pin_number, true, false,
+ true, 8, false, // TX, auto pull every 8 bits. shift left to output msb first
+ false, 32, true, // RX setting we don't use
+ false); // claim pins
+ if (!ok) {
+ // Do nothing. Maybe bitbang?
+ return;
+ }
+
+ // Wait to make sure we don't append onto the last transmission. This should only be a tick or
+ // two.
+ while (port_get_raw_ticks(NULL) < next_start_raw_ticks) {}
+
+ common_hal_rp2pio_statemachine_write(&state_machine, pixels, num_bytes);
+
+ // Use a private deinit of the state machine that doesn't reset the pin.
+ rp2pio_statemachine_deinit(&state_machine, true);
+ gpio_init(digitalinout->pin->number);
+ // 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
new file mode 100644
index 000000000..dcbd06e93
--- /dev/null
+++ b/ports/raspberrypi/common-hal/os/__init__.c
@@ -0,0 +1,62 @@
+/*
+ * 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 "genhdr/mpversion.h"
+#include "py/mpconfig.h"
+#include "py/objstr.h"
+#include "py/objtuple.h"
+#include "py/qstr.h"
+
+
+STATIC const qstr os_uname_info_fields[] = {
+ MP_QSTR_sysname, MP_QSTR_nodename,
+ MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
+};
+STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "rp2040");
+STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "rp2040");
+STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING);
+STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
+STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
+
+
+STATIC MP_DEFINE_ATTRTUPLE(
+ os_uname_info_obj,
+ os_uname_info_fields,
+ 5,
+ (mp_obj_t)&os_uname_info_sysname_obj,
+ (mp_obj_t)&os_uname_info_nodename_obj,
+ (mp_obj_t)&os_uname_info_release_obj,
+ (mp_obj_t)&os_uname_info_version_obj,
+ (mp_obj_t)&os_uname_info_machine_obj
+);
+
+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;
+}
diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c
new file mode 100644
index 000000000..567ec5ef5
--- /dev/null
+++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c
@@ -0,0 +1,216 @@
+/*
+ * 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 <stdint.h>
+
+#include "py/runtime.h"
+#include "common-hal/pwmio/PWMOut.h"
+#include "shared-bindings/pwmio/PWMOut.h"
+#include "shared-bindings/microcontroller/Processor.h"
+
+#include "supervisor/shared/translate.h"
+
+#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
+#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h"
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h"
+
+uint32_t target_slice_frequencies[NUM_PWM_SLICES];
+uint32_t slice_fixed_frequency;
+
+#define CHANNELS_PER_SLICE 2
+static uint32_t channel_use;
+static uint32_t never_reset_channel;
+
+static uint32_t _mask(uint8_t slice, uint8_t channel) {
+ return 1 << (slice * CHANNELS_PER_SLICE + channel);
+}
+
+void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) {
+ never_reset_channel |= _mask(self->slice, self->channel);
+
+ never_reset_pin_number(self->pin->number);
+}
+
+void common_hal_pwmio_pwmout_reset_ok(pwmio_pwmout_obj_t *self) {
+ never_reset_channel &= ~_mask(self->slice, self->channel);
+}
+
+void pwmout_reset(void) {
+ // Reset all slices
+ for (size_t slice = 0; slice < NUM_PWM_SLICES; slice++) {
+ bool reset = true;
+ for (size_t channel = 0; channel < CHANNELS_PER_SLICE; channel++) {
+ uint32_t channel_use_mask = _mask(slice, channel);
+ if ((never_reset_channel & channel_use_mask) != 0) {
+ reset = false;
+ continue;
+ }
+ channel_use &= ~channel_use_mask;
+ }
+ if (!reset) {
+ continue;
+ }
+ pwm_set_enabled(slice, false);
+ target_slice_frequencies[slice] = 0;
+ slice_fixed_frequency &= ~(1 << slice);
+ }
+}
+
+pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t* self,
+ const mcu_pin_obj_t* pin,
+ uint16_t duty,
+ uint32_t frequency,
+ bool variable_frequency) {
+ self->pin = pin;
+ self->variable_frequency = variable_frequency;
+ self->duty_cycle = duty;
+
+ if (frequency == 0 || frequency > (common_hal_mcu_processor_get_frequency() / 2)) {
+ return PWMOUT_INVALID_FREQUENCY;
+ }
+
+ uint8_t slice = pwm_gpio_to_slice_num(pin->number);
+ uint8_t channel = pwm_gpio_to_channel(pin->number);
+ uint32_t channel_use_mask = _mask(slice, channel);
+
+ // Check the channel first.
+ if ((channel_use & channel_use_mask) != 0) {
+ return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
+ }
+ // Now check if the slice is in use and if we can share with it.
+ if (target_slice_frequencies[slice] > 0) {
+ // If we want to change frequency then we can't share.
+ 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) {
+ 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.
+ if (target_slice_frequencies[slice] != frequency) {
+ return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE;
+ }
+ }
+ self->slice = slice;
+ self->channel = channel;
+ channel_use |= channel_use_mask;
+ if (!variable_frequency) {
+ slice_fixed_frequency |= 1 << slice;
+ }
+
+ if (target_slice_frequencies[slice] != frequency) {
+ // Reset the counter and compare values.
+ pwm_hw->slice[slice].ctr = PWM_CH0_CTR_RESET;
+ common_hal_pwmio_pwmout_set_duty_cycle(self, duty);
+ common_hal_pwmio_pwmout_set_frequency(self, frequency);
+ pwm_set_enabled(slice, true);
+ } else {
+ common_hal_pwmio_pwmout_set_duty_cycle(self, duty);
+ }
+
+ // Connect to the pad last to avoid any glitches from changing settings.
+ gpio_set_function(pin->number, GPIO_FUNC_PWM);
+
+ return PWMOUT_OK;
+}
+
+bool common_hal_pwmio_pwmout_deinited(pwmio_pwmout_obj_t* self) {
+ return self->pin == NULL;
+}
+
+void common_hal_pwmio_pwmout_deinit(pwmio_pwmout_obj_t* self) {
+ if (common_hal_pwmio_pwmout_deinited(self)) {
+ return;
+ }
+ uint32_t channel_mask = _mask(self->slice, self->channel);
+ channel_use &= ~channel_mask;
+ never_reset_channel &= ~channel_mask;
+ 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);
+ pwm_set_enabled(self->slice, false);
+ }
+
+ reset_pin_number(self->pin->number);
+ self->pin = NULL;
+}
+
+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);
+}
+
+uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t* self) {
+ return self->duty_cycle;
+}
+
+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"));
+ }
+
+ 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))) {
+ // 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.
+ uint64_t frequency16 = ((uint64_t) clock_get_hz(clk_sys)) / (1 << 12);
+ uint64_t div16 = frequency16 / frequency;
+ // Round the divisor to try and get closest to the target frequency. We could
+ // also always round up and use TOP to get us closer. We may not need that though.
+ if (frequency16 % frequency >= frequency / 2) {
+ div16 += 1;
+ }
+ if (div16 >= (1 << 12)) {
+ div16 = (1 << 12) - 1;
+ }
+ self->actual_frequency = frequency16 / div16;
+ self->top = 1 << 16;
+ pwm_set_clkdiv_int_frac(self->slice, div16 / 16, div16 % 16);
+ pwm_set_wrap(self->slice, self->top - 1);
+ } else {
+ uint32_t top = common_hal_mcu_processor_get_frequency() / frequency;
+ 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 - 1);
+ }
+ common_hal_pwmio_pwmout_set_duty_cycle(self, self->duty_cycle);
+}
+
+uint32_t common_hal_pwmio_pwmout_get_frequency(pwmio_pwmout_obj_t* self) {
+ return self->actual_frequency;
+}
+
+bool common_hal_pwmio_pwmout_get_variable_frequency(pwmio_pwmout_obj_t* self) {
+ return self->variable_frequency;
+}
diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.h b/ports/raspberrypi/common-hal/pwmio/PWMOut.h
new file mode 100644
index 000000000..50f84777b
--- /dev/null
+++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.h
@@ -0,0 +1,47 @@
+/*
+ * 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_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ const mcu_pin_obj_t *pin;
+ uint8_t slice;
+ uint8_t channel;
+ bool variable_frequency;
+ uint16_t duty_cycle;
+ uint32_t actual_frequency;
+ uint32_t top;
+} pwmio_pwmout_obj_t;
+
+void pwmout_reset(void);
+
+#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H
diff --git a/ports/raspberrypi/common-hal/pwmio/__init__.c b/ports/raspberrypi/common-hal/pwmio/__init__.c
new file mode 100644
index 000000000..9e551a107
--- /dev/null
+++ b/ports/raspberrypi/common-hal/pwmio/__init__.c
@@ -0,0 +1 @@
+// No pwmio module functions.
diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c
new file mode 100644
index 000000000..6510410b0
--- /dev/null
+++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c
@@ -0,0 +1,585 @@
+/*
+ * 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 "bindings/rp2pio/StateMachine.h"
+
+#include "common-hal/microcontroller/__init__.h"
+#include "shared-bindings/microcontroller/Pin.h"
+
+#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
+#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h"
+#include "src/rp2_common/hardware_dma/include/hardware/dma.h"
+#include "src/rp2_common/hardware_pio/include/hardware/pio_instructions.h"
+#include "src/rp2040/hardware_structs/include/hardware/structs/iobank0.h"
+
+#include "lib/utils/interrupt_char.h"
+#include "py/obj.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+
+// Count how many state machines are using each pin.
+STATIC uint8_t _pin_reference_count[TOTAL_GPIO_COUNT];
+STATIC uint32_t _current_program_id[NUM_PIOS][NUM_PIO_STATE_MACHINES];
+STATIC uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
+STATIC uint8_t _current_program_len[NUM_PIOS][NUM_PIO_STATE_MACHINES];
+STATIC bool _never_reset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
+
+STATIC uint32_t _current_pins[NUM_PIOS];
+STATIC uint32_t _current_sm_pins[NUM_PIOS][NUM_PIO_STATE_MACHINES];
+
+STATIC PIO pio_instances[2] = {pio0, pio1};
+
+void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
+ uint8_t pio_index = pio_get_index(pio);
+ pio_sm_unclaim(pio, sm);
+ uint32_t program_id = _current_program_id[pio_index][sm];
+ if (program_id == 0) {
+ return;
+ }
+ _current_program_id[pio_index][sm] = 0;
+ bool program_in_use = false;
+ for (size_t i = 0; i < NUM_PIO_STATE_MACHINES; i++) {
+ if (_current_program_id[pio_index][i] == program_id) {
+ program_in_use = true;
+ break;
+ }
+ }
+ if (!program_in_use) {
+ uint8_t offset = _current_program_offset[pio_index][sm];
+ pio_program_t program_struct = {
+ .length = _current_program_len[pio_index][sm]
+ };
+ pio_remove_program(pio, &program_struct, offset);
+ }
+
+ uint32_t pins = _current_sm_pins[pio_index][sm];
+ for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
+ if ((pins & (1 << pin_number)) == 0) {
+ continue;
+ }
+ _pin_reference_count[pin_number]--;
+ if (_pin_reference_count[pin_number] == 0) {
+ if (!leave_pins) {
+ reset_pin_number(pin_number);
+ }
+ _current_pins[pio_index] &= ~(1 << pin_number);
+ }
+ }
+ _current_sm_pins[pio_index][sm] = 0;
+}
+
+void reset_rp2pio_statemachine(void) {
+ for (size_t i = 0; i < NUM_PIOS; i++) {
+ PIO pio = pio_instances[i];
+ for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) {
+ if (_never_reset[i][j]) {
+ continue;
+ }
+ _reset_statemachine(pio, j, false);
+ }
+ }
+}
+
+STATIC uint32_t _check_pins_free(const mcu_pin_obj_t * first_pin, uint8_t pin_count, bool exclusive_pin_use) {
+ uint32_t pins_we_use = 0;
+ if (first_pin != NULL) {
+ for (size_t i = 0; i < pin_count; i++) {
+ uint8_t pin_number = first_pin->number + i;
+ if (pin_number >= TOTAL_GPIO_COUNT) {
+ mp_raise_ValueError(translate("Pin count too large"));
+ }
+ const mcu_pin_obj_t * pin = mcu_pin_global_dict_table[pin_number].value;
+ if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) {
+ assert_pin_free(pin);
+ }
+ pins_we_use |= 1 << pin_number;
+ }
+ }
+ return pins_we_use;
+}
+
+
+bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
+ const uint16_t* program, size_t program_len,
+ size_t frequency,
+ const uint16_t* init, size_t init_len,
+ const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
+ const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
+ const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
+ const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
+ uint32_t pins_we_use, bool tx_fifo, bool rx_fifo,
+ bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
+ bool auto_push, uint8_t push_threshold, bool in_shift_right,
+ bool claim_pins) {
+ // Create a program id that isn't the pointer so we can store it without storing the original object.
+ uint32_t program_id = ~((uint32_t) program);
+
+ // Next, find a PIO and state machine to use.
+ size_t pio_index = NUM_PIOS;
+ uint8_t program_offset = 32;
+ pio_program_t program_struct = {
+ .instructions = (uint16_t*) program,
+ .length = program_len,
+ .origin = 0
+ };
+ for (size_t i = 0; i < NUM_PIOS; i++) {
+ PIO pio = pio_instances[i];
+ uint8_t free_count = 0;
+ for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) {
+ if (_current_program_id[i][j] == program_id &&
+ _current_program_len[i][j] == program_len) {
+ program_offset = _current_program_offset[i][j];
+ }
+ int temp_claim = pio_claim_unused_sm(pio, false);
+ if (temp_claim >= 0) {
+ pio_sm_unclaim(pio, temp_claim);
+ free_count++;
+ }
+ }
+ if (free_count > 0 && (program_offset < 32 || pio_can_add_program(pio, &program_struct))) {
+ pio_index = i;
+ if (program_offset < 32) {
+ break;
+ }
+ }
+ // Reset program offset if we weren't able to find a free state machine
+ // on that PIO. (We would have broken the loop otherwise.)
+ program_offset = 32;
+ }
+
+ int state_machine = -1;
+ if (pio_index < NUM_PIOS) {
+ PIO pio = pio_instances[pio_index];
+ for (size_t i = 0; i < NUM_PIOS; i++) {
+ if (i == pio_index) {
+ continue;
+ }
+ if ((_current_pins[i] & pins_we_use) != 0) {
+ // Pin in use by another PIO already.
+ return false;
+ }
+ }
+ state_machine = pio_claim_unused_sm(pio, false);
+ }
+ if (pio_index == NUM_PIOS || state_machine < 0 || state_machine >= NUM_PIO_STATE_MACHINES) {
+ return false;
+ }
+
+ self->pio = pio_instances[pio_index];
+ self->state_machine = state_machine;
+ if (program_offset == 32) {
+ program_offset = pio_add_program(self->pio, &program_struct);
+ }
+ _current_program_id[pio_index][state_machine] = program_id;
+ _current_program_len[pio_index][state_machine] = program_len;
+ _current_program_offset[pio_index][state_machine] = program_offset;
+ _current_sm_pins[pio_index][state_machine] = pins_we_use;
+ _current_pins[pio_index] |= pins_we_use;
+
+ for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
+ if ((pins_we_use & (1 << pin_number)) == 0) {
+ continue;
+ }
+ _pin_reference_count[pin_number]++;
+ const mcu_pin_obj_t * pin = mcu_pin_global_dict_table[pin_number].value;
+ // Also claim the pin at the top level when we're the first to grab it.
+ if (_pin_reference_count[pin_number] == 1) {
+ if (claim_pins) {
+ claim_pin(pin);
+ }
+ pio_gpio_init(self->pio, pin_number);
+ }
+ }
+
+ pio_sm_config c = {0, 0, 0};
+
+ if (frequency == 0) {
+ frequency = clock_get_hz(clk_sys);
+ }
+ uint64_t frequency256 = ((uint64_t) clock_get_hz(clk_sys)) * 256;
+ uint64_t div256 = frequency256 / frequency;
+ if (frequency256 % div256 > 0) {
+ div256 += 1;
+ }
+ self->actual_frequency = frequency256 / div256;
+ sm_config_set_clkdiv_int_frac(&c, div256 / 256, div256 % 256);
+
+ if (first_out_pin != NULL) {
+ sm_config_set_out_pins(&c, first_out_pin->number, out_pin_count);
+ }
+ if (first_in_pin != NULL) {
+ sm_config_set_in_pins(&c, first_in_pin->number);
+ }
+ if (first_set_pin != NULL) {
+ sm_config_set_set_pins(&c, first_set_pin->number, set_pin_count);
+ }
+ if (first_sideset_pin != NULL) {
+ sm_config_set_sideset(&c, sideset_pin_count, false /* optional */, false /* pin direction */);
+ sm_config_set_sideset_pins(&c, first_sideset_pin->number);
+ }
+ sm_config_set_wrap(&c, program_offset, program_offset + program_len - 1);
+ sm_config_set_in_shift(&c, in_shift_right, auto_push, push_threshold);
+ sm_config_set_out_shift(&c, out_shift_right, auto_pull, pull_threshold);
+
+ enum pio_fifo_join join = PIO_FIFO_JOIN_NONE;
+ if (!rx_fifo) {
+ join = PIO_FIFO_JOIN_TX;
+ } else if (!tx_fifo) {
+ join = PIO_FIFO_JOIN_RX;
+ }
+ if (rx_fifo) {
+ self->rx_dreq = pio_get_dreq(self->pio, self->state_machine, false);
+ }
+ if (tx_fifo) {
+ self->tx_dreq = pio_get_dreq(self->pio, self->state_machine, true);
+ }
+ self->in = rx_fifo;
+ self->out = tx_fifo;
+ self->out_shift_right = out_shift_right;
+ self->in_shift_right = in_shift_right;
+
+ sm_config_set_fifo_join(&c, join);
+
+ pio_sm_init(self->pio, self->state_machine, program_offset, &c);
+ pio_sm_set_enabled(self->pio, self->state_machine, true);
+ for (size_t i = 0; i < init_len; i++) {
+ pio_sm_exec(self->pio, self->state_machine, init[i]);
+ }
+ return true;
+}
+
+void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
+ const uint16_t* program, size_t program_len,
+ size_t frequency,
+ const uint16_t* init, size_t init_len,
+ const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
+ const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
+ const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
+ const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
+ bool exclusive_pin_use,
+ bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
+ bool auto_push, uint8_t push_threshold, bool in_shift_right) {
+
+ // First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
+ uint32_t pins_we_use = 0;
+ pins_we_use |= _check_pins_free(first_out_pin, out_pin_count, exclusive_pin_use);
+ pins_we_use |= _check_pins_free(first_in_pin, in_pin_count, exclusive_pin_use);
+ pins_we_use |= _check_pins_free(first_set_pin, set_pin_count, exclusive_pin_use);
+ pins_we_use |= _check_pins_free(first_sideset_pin, sideset_pin_count, exclusive_pin_use);
+
+ // Look through the program to see what we reference and make sure it was provided.
+ bool tx_fifo = false;
+ bool rx_fifo = false;
+ bool in_loaded = false; // can be loaded in other ways besides the fifo
+ bool out_loaded = false;
+ bool in_used = false;
+ bool out_used = false;
+ for (size_t i = 0; i < program_len; i++) {
+ uint16_t full_instruction = program[i];
+ uint16_t instruction = full_instruction & 0xe000;
+ if (instruction == 0x8000) {
+ if ((full_instruction & 0xe080) == pio_instr_bits_push) {
+ rx_fifo = true;
+ in_loaded = true;
+ } else { // pull otherwise.
+ tx_fifo = true;
+ out_loaded = true;
+ }
+ }
+ if (instruction == pio_instr_bits_jmp) {
+ uint16_t condition = (full_instruction & 0x00e0) >> 5;
+ if (condition == 0x6) { // GPIO
+ mp_raise_NotImplementedError_varg(translate("Instruction %d jumps on pin"), i);
+ }
+ }
+ if (instruction == pio_instr_bits_wait) {
+ uint16_t wait_source = (full_instruction & 0x0060) >> 5;
+ uint16_t wait_index = full_instruction & 0x001f;
+ if (wait_source == 0 && (pins_we_use & (1 << wait_index)) == 0) { // GPIO
+ mp_raise_ValueError_varg(translate("Instruction %d uses extra pin"), i);
+ }
+ if (wait_source == 1) { // Input pin
+ if (first_in_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_in_pin. Instruction %d waits based on pin"), i);
+ }
+ if (wait_index > in_pin_count) {
+ mp_raise_ValueError_varg(translate("Instruction %d waits on input outside of count"), i);
+ }
+ }
+ }
+ if (instruction == pio_instr_bits_in) {
+ uint16_t source = (full_instruction & 0x00e0) >> 5;
+ uint16_t bit_count = full_instruction & 0x001f;
+ if (source == 0) {
+ if (first_in_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_in_pin. Instruction %d shifts in from pin(s)"), i);
+ }
+ if (bit_count > in_pin_count) {
+ mp_raise_ValueError_varg(translate("Instruction %d shifts in more bits than pin count"), i);
+ }
+ }
+ if (auto_push) {
+ in_loaded = true;
+ rx_fifo = true;
+ }
+ in_used = true;
+ }
+ if (instruction == pio_instr_bits_out) {
+ uint16_t bit_count = full_instruction & 0x001f;
+ uint16_t destination = (full_instruction & 0x00e0) >> 5;
+ // Check for pins or pindirs destination.
+ if (destination == 0x0 || destination == 0x4) {
+ if (first_out_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_out_pin. Instruction %d shifts out to pin(s)"), i);
+ }
+ if (bit_count > out_pin_count) {
+ mp_raise_ValueError_varg(translate("Instruction %d shifts out more bits than pin count"), i);
+ }
+ }
+ if (auto_pull) {
+ out_loaded = true;
+ tx_fifo = true;
+ }
+ out_used = true;
+ }
+ if (instruction == pio_instr_bits_set) {
+ uint16_t destination = (full_instruction & 0x00e0) >> 5;
+ // Check for pins or pindirs destination.
+ if ((destination == 0x00 || destination == 0x4) && first_set_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_set_pin. Instruction %d sets pin(s)"), i);
+ }
+ }
+ if (instruction == pio_instr_bits_mov) {
+ uint16_t source = full_instruction & 0x0007;
+ uint16_t destination = (full_instruction & 0x00e0) >> 5;
+ // Check for pins or pindirs destination.
+ if (destination == 0x0 && first_out_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_out_pin. Instruction %d writes pin(s)"), i);
+ }
+ if (source == 0x0 && first_in_pin == NULL) {
+ mp_raise_ValueError_varg(translate("Missing first_in_pin. Instruction %d reads pin(s)"), i);
+ }
+ if (destination == 0x6) {
+ in_loaded = true;
+ } else if (destination == 0x7) {
+ out_loaded = true;
+ }
+ }
+ }
+
+ if (!in_loaded && in_used) {
+ mp_raise_ValueError_varg(translate("Program does IN without loading ISR"));
+ }
+ if (!out_loaded && out_used) {
+ mp_raise_ValueError_varg(translate("Program does OUT without loading OSR"));
+ }
+
+ if (in_pin_count > 8 || out_pin_count > 8) {
+ mp_raise_NotImplementedError(translate("Only IN/OUT of up to 8 supported"));
+ }
+
+ bool ok = rp2pio_statemachine_construct(self,
+ program, program_len,
+ frequency,
+ init, init_len,
+ first_out_pin, out_pin_count,
+ first_in_pin, in_pin_count,
+ first_set_pin, set_pin_count,
+ first_sideset_pin, sideset_pin_count,
+ pins_we_use, tx_fifo, rx_fifo,
+ auto_pull, pull_threshold, out_shift_right,
+ auto_push, push_threshold, in_shift_right,
+ true /* claim pins */);
+ if (!ok) {
+ mp_raise_RuntimeError(translate("All state machines in use"));
+ }
+}
+
+uint32_t common_hal_rp2pio_statemachine_get_frequency(rp2pio_statemachine_obj_t* self) {
+ return self->actual_frequency;
+}
+
+void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins) {
+ uint8_t sm = self->state_machine;
+ uint8_t pio_index = pio_get_index(self->pio);
+ _never_reset[pio_index][sm] = false;
+ _reset_statemachine(self->pio, sm, leave_pins);
+ self->state_machine = NUM_PIO_STATE_MACHINES;
+}
+
+void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self) {
+ rp2pio_statemachine_deinit(self, false);
+}
+
+void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self) {
+ uint8_t sm = self->state_machine;
+ uint8_t pio_index = pio_get_index(self->pio);
+ _never_reset[pio_index][sm] = true;
+ // TODO: never reset all the pins
+}
+
+bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self) {
+ return self->state_machine == NUM_PIO_STATE_MACHINES;
+}
+
+static bool _transfer(rp2pio_statemachine_obj_t *self,
+ const uint8_t *data_out, size_t out_len,
+ uint8_t *data_in, size_t in_len) {
+ // This implementation is based on SPI but varies because the tx and rx buffers
+ // may be different lengths and occur at different times or speeds.
+
+ // Use DMA for large transfers if channels are available
+ const size_t dma_min_size_threshold = 32;
+ int chan_tx = -1;
+ int chan_rx = -1;
+ size_t len = MAX(out_len, in_len);
+ bool tx = data_out != NULL;
+ bool rx = data_in != NULL;
+ if (len >= dma_min_size_threshold) {
+ // Use DMA channels to service the two FIFOs
+ if (tx) {
+ chan_tx = dma_claim_unused_channel(false);
+ }
+ if (rx) {
+ chan_rx = dma_claim_unused_channel(false);
+ }
+ }
+ volatile uint8_t* tx_destination = NULL;
+ const volatile uint8_t* rx_source = NULL;
+ if (tx) {
+ tx_destination = (volatile uint8_t*) &self->pio->txf[self->state_machine];
+ if (!self->out_shift_right) {
+ tx_destination += 3;
+ }
+ }
+ if (rx) {
+ rx_source = (const volatile uint8_t*) &self->pio->rxf[self->state_machine];
+ if (!self->in_shift_right) {
+ rx_source += 3;
+ }
+ }
+ bool use_dma = (!rx || chan_rx >= 0) && (!tx || chan_tx >= 0);
+ if (use_dma) {
+ dma_channel_config c;
+ uint32_t channel_mask = 0;
+ if (tx) {
+ c = dma_channel_get_default_config(chan_tx);
+ channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
+ channel_config_set_dreq(&c, self->tx_dreq);
+ channel_config_set_read_increment(&c, true);
+ channel_config_set_write_increment(&c, false);
+ dma_channel_configure(chan_tx, &c,
+ tx_destination,
+ data_out,
+ len,
+ false);
+ channel_mask |= 1u << chan_tx;
+ }
+ if (rx) {
+ c = dma_channel_get_default_config(chan_rx);
+ channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
+ channel_config_set_dreq(&c, self->rx_dreq);
+ channel_config_set_read_increment(&c, false);
+ channel_config_set_write_increment(&c, true);
+ dma_channel_configure(chan_rx, &c,
+ data_in,
+ rx_source,
+ len,
+ false);
+ channel_mask |= 1u << chan_rx;
+ }
+
+ dma_start_channel_mask(channel_mask);
+ while ((rx && dma_channel_is_busy(chan_rx)) ||
+ (tx && dma_channel_is_busy(chan_tx))) {
+ // TODO: We should idle here until we get a DMA interrupt or something else.
+ RUN_BACKGROUND_TASKS;
+ if (mp_hal_is_interrupted()) {
+ if (rx && dma_channel_is_busy(chan_rx)) {
+ dma_channel_abort(chan_rx);
+ }
+ if (tx && dma_channel_is_busy(chan_tx)) {
+ dma_channel_abort(chan_tx);
+ }
+ break;
+ }
+ }
+ // Clear the stall bit so we can detect when the state machine is done transmitting.
+ self->pio->fdebug = PIO_FDEBUG_TXSTALL_BITS;
+ }
+
+ // If we have claimed only one channel successfully, we should release immediately. This also
+ // releases the DMA after use_dma has been done.
+ if (chan_rx >= 0) {
+ dma_channel_unclaim(chan_rx);
+ }
+ if (chan_tx >= 0) {
+ dma_channel_unclaim(chan_tx);
+ }
+
+ if (!use_dma && !mp_hal_is_interrupted()) {
+ // Use software for small transfers, or if couldn't claim two DMA channels
+ size_t rx_remaining = in_len;
+ 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;
+ }
+ RUN_BACKGROUND_TASKS;
+ if (mp_hal_is_interrupted()) {
+ break;
+ }
+ }
+ // Clear the stall bit so we can detect when the state machine is done transmitting.
+ self->pio->fdebug = PIO_FDEBUG_TXSTALL_BITS;
+ }
+ // Wait for the state machine to finish transmitting the data we've queued
+ // up.
+ if (tx) {
+ while (!pio_sm_is_tx_fifo_empty(self->pio, self->state_machine) ||
+ (self->pio->fdebug & PIO_FDEBUG_TXSTALL_BITS) == 0) {
+ RUN_BACKGROUND_TASKS;
+ }
+ }
+ return true;
+}
+
+// Writes out the given data.
+bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self,
+ const uint8_t *data, size_t len) {
+ if (!self->out) {
+ mp_raise_RuntimeError(translate("No out in program"));
+ }
+ return _transfer(self, data, len, NULL, 0);
+}
diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.h b/ports/raspberrypi/common-hal/rp2pio/StateMachine.h
new file mode 100644
index 000000000..6b70b6b5b
--- /dev/null
+++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.h
@@ -0,0 +1,68 @@
+/*
+ * 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_COMMON_HAL_RP2PIO_STATEMACHINE_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_RP2PIO_STATEMACHINE_H
+
+#include "py/obj.h"
+
+#include "src/rp2_common/hardware_pio/include/hardware/pio.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint32_t pins; // Bitmask of what pins this state machine uses.
+ int state_machine;
+ PIO pio;
+ bool in;
+ bool out;
+ uint tx_dreq;
+ uint rx_dreq;
+ bool out_shift_right;
+ bool in_shift_right;
+ uint32_t actual_frequency;
+} rp2pio_statemachine_obj_t;
+
+void reset_rp2pio_statemachine(void);
+
+// Minimal internal version that only fails on pin error (not in use) or full PIO.
+bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
+ const uint16_t* program, size_t program_len,
+ size_t frequency,
+ const uint16_t* init, size_t init_len,
+ const mcu_pin_obj_t * first_out_pin, uint8_t out_pin_count,
+ const mcu_pin_obj_t * first_in_pin, uint8_t in_pin_count,
+ const mcu_pin_obj_t * first_set_pin, uint8_t set_pin_count,
+ const mcu_pin_obj_t * first_sideset_pin, uint8_t sideset_pin_count,
+ uint32_t pins_we_use, bool tx_fifo, bool rx_fifo,
+ bool auto_pull, uint8_t pull_threshold, bool out_shift_right,
+ bool auto_push, uint8_t push_threshold, bool in_shift_right,
+ bool claim_pins);
+
+void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins);
+
+extern const mp_obj_type_t rp2pio_statemachine_type;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_RP2PIO_STATEMACHINE_H
diff --git a/ports/raspberrypi/common-hal/rp2pio/__init__.c b/ports/raspberrypi/common-hal/rp2pio/__init__.c
new file mode 100644
index 000000000..21699dfa3
--- /dev/null
+++ b/ports/raspberrypi/common-hal/rp2pio/__init__.c
@@ -0,0 +1 @@
+// Nothing yet.
diff --git a/ports/raspberrypi/common-hal/supervisor/Runtime.c b/ports/raspberrypi/common-hal/supervisor/Runtime.c
new file mode 100755
index 000000000..6be38f216
--- /dev/null
+++ b/ports/raspberrypi/common-hal/supervisor/Runtime.c
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * 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 <stdbool.h>
+#include "shared-bindings/supervisor/Runtime.h"
+#include "supervisor/serial.h"
+
+bool common_hal_get_serial_connected(void) {
+ return (bool) serial_connected();
+}
+
+bool common_hal_get_serial_bytes_available(void) {
+ return (bool) serial_bytes_available();
+}
diff --git a/ports/raspberrypi/common-hal/supervisor/Runtime.h b/ports/raspberrypi/common-hal/supervisor/Runtime.h
new file mode 100755
index 000000000..45db489bd
--- /dev/null
+++ b/ports/raspberrypi/common-hal/supervisor/Runtime.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * 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_SUPERVISOR_RUNTIME_H
+#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_SUPERVISOR_RUNTIME_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Stores no state currently.
+} super_runtime_obj_t;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_SUPERVISOR_RUNTIME_H
diff --git a/ports/raspberrypi/common-hal/supervisor/__init__.c b/ports/raspberrypi/common-hal/supervisor/__init__.c
new file mode 100755
index 000000000..6dca35fb5
--- /dev/null
+++ b/ports/raspberrypi/common-hal/supervisor/__init__.c
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Michael Schroeder
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "py/obj.h"
+
+#include "shared-bindings/supervisor/__init__.h"
+#include "shared-bindings/supervisor/Runtime.h"
+
+
+// The singleton supervisor.Runtime object, bound to supervisor.runtime
+// It currently only has properties, and no state.
+const super_runtime_obj_t common_hal_supervisor_runtime_obj = {
+ .base = {
+ .type = &supervisor_runtime_type,
+ },
+};
diff --git a/ports/raspberrypi/fatfs_port.c b/ports/raspberrypi/fatfs_port.c
new file mode 100644
index 000000000..c65a73a42
--- /dev/null
+++ b/ports/raspberrypi/fatfs_port.c
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
+ *
+ * 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/mphal.h"
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h" /* FatFs lower layer API */
+#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */
+#include "lib/timeutils/timeutils.h"
+
+#if CIRCUITPY_RTC
+#include "shared-bindings/rtc/RTC.h"
+#endif
+
+DWORD get_fattime(void) {
+#if CIRCUITPY_RTC
+ timeutils_struct_time_t tm;
+ common_hal_rtc_get_time(&tm);
+ return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) |
+ (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1);
+#else
+ return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2);
+#endif
+
+
+}
diff --git a/ports/raspberrypi/link.ld b/ports/raspberrypi/link.ld
new file mode 100644
index 000000000..d642fd680
--- /dev/null
+++ b/ports/raspberrypi/link.ld
@@ -0,0 +1,250 @@
+/* Based on GCC ARM embedded samples.
+ Defines the following symbols for use by code:
+ __exidx_start
+ __exidx_end
+ __etext
+ __data_start__
+ __preinit_array_start
+ __preinit_array_end
+ __init_array_start
+ __init_array_end
+ __fini_array_start
+ __fini_array_end
+ __data_end__
+ __bss_start__
+ __bss_end__
+ __end__
+ end
+ __HeapLimit
+ __StackLimit
+ __StackTop
+ __stack (== StackTop)
+*/
+
+MEMORY
+{
+ FLASH_FIRMWARE (rx) : ORIGIN = 0x10000000, LENGTH = 1024k
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k
+ SCRATCH_X (rwx) : ORIGIN = 0x20040000, LENGTH = 4k
+ SCRATCH_Y (rwx) : ORIGIN = 0x20041000, LENGTH = 4k
+}
+
+ENTRY(_entry_point)
+
+SECTIONS
+{
+ /* Second stage bootloader is prepended to the image. It must be 256 bytes big
+ and checksummed. It is usually built by the boot_stage2 target
+ in the Pico SDK
+ */
+
+ .flash_begin : {
+ __flash_binary_start = .;
+ } > FLASH_FIRMWARE
+
+ .boot2 : {
+ __boot2_start__ = .;
+ KEEP (*(.boot2))
+ __boot2_end__ = .;
+ } > FLASH_FIRMWARE
+
+ ASSERT(__boot2_end__ - __boot2_start__ == 256,
+ "ERROR: Pico second stage bootloader must be 256 bytes in size")
+
+ /* The second stage will always enter the image at the start of .text.
+ The debugger will use the ELF entry point, which is the _entry_point
+ symbol if present, otherwise defaults to start of .text.
+ This can be used to transfer control back to the bootrom on debugger
+ launches only, to perform proper flash setup.
+ */
+
+ .text : {
+ __reset_start = .;
+ KEEP (*(.reset))
+ . = ALIGN(256);
+ __reset_end = .;
+ ASSERT(__reset_end - __reset_start == 256, "ERROR: reset section should only be 256 bytes");
+ KEEP (*(.vectors))
+ /* TODO revisit this now memset/memcpy/float in ROM */
+ /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
+ * FLASH ... we will include any thing excluded here in .data below by default */
+ *(.init)
+ *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
+ *(.fini)
+ /* Pull all c'tors into .text */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+ /* Followed by destructors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.eh_frame*)
+ . = ALIGN(4);
+ } > FLASH_FIRMWARE
+
+ .rodata : {
+ *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
+ . = ALIGN(4);
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
+ . = ALIGN(4);
+ } > FLASH_FIRMWARE
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH_FIRMWARE
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH_FIRMWARE
+ __exidx_end = .;
+
+ /* Machine inspectable binary information */
+ . = ALIGN(4);
+ __binary_info_start = .;
+ .binary_info :
+ {
+ KEEP(*(.binary_info.keep.*))
+ *(.binary_info.*)
+ } > FLASH_FIRMWARE
+ __binary_info_end = .;
+ . = ALIGN(4);
+
+ /* End of .text-like segments */
+ __etext = .;
+
+ .ram_vector_table (COPY): {
+ *(.ram_vector_table)
+ } > RAM
+
+ .data : {
+ __data_start__ = .;
+ *(vtable)
+
+ *(.time_critical*)
+
+ /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
+ *(.text*)
+ . = ALIGN(4);
+ *(.rodata*)
+ . = ALIGN(4);
+
+ *(.data*)
+
+ . = ALIGN(4);
+ *(.after_data.*)
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__mutex_array_start = .);
+ KEEP(*(SORT(.mutex_array.*)))
+ KEEP(*(.mutex_array))
+ PROVIDE_HIDDEN (__mutex_array_end = .);
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(SORT(.preinit_array.*)))
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ *(SORT(.fini_array.*))
+ *(.fini_array)
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.jcr)
+ . = ALIGN(4);
+ /* All data end */
+ __data_end__ = .;
+ } > RAM AT> FLASH_FIRMWARE
+
+ .uninitialized_data (COPY): {
+ . = ALIGN(4);
+ *(.uninitialized_data*)
+ } > RAM
+
+ /* Start and end symbols must be word-aligned */
+ .scratch_x : {
+ __scratch_x_start__ = .;
+ *(.scratch_x.*)
+ . = ALIGN(4);
+ __scratch_x_end__ = .;
+ } > SCRATCH_X AT > FLASH_FIRMWARE
+ __scratch_x_source__ = LOADADDR(.scratch_x);
+
+ .scratch_y : {
+ __scratch_y_start__ = .;
+ *(.scratch_y.*)
+ . = ALIGN(4);
+ __scratch_y_end__ = .;
+ } > SCRATCH_Y AT > FLASH_FIRMWARE
+ __scratch_y_source__ = LOADADDR(.scratch_y);
+
+ .bss : {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > RAM
+
+ .heap (COPY):
+ {
+ __end__ = .;
+ end = __end__;
+ *(.heap*)
+ __HeapLimit = .;
+ } > RAM
+
+ /* .stack*_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later
+ *
+ * stack1 section may be empty/missing if platform_launch_core1 is not used */
+
+ /* by default we put core 0 stack at the end of scratch Y, so that if core 1
+ * stack is not used then all of SCRATCH_X is free.
+ */
+ .stack1_dummy (COPY):
+ {
+ *(.stack1*)
+ } > SCRATCH_X
+ .stack_dummy (COPY):
+ {
+ *(.stack*)
+ } > SCRATCH_Y
+
+ .flash_end : {
+ __flash_binary_end = .;
+ } > FLASH_FIRMWARE
+
+ /* stack limit is poorly named, but historically is maximum heap ptr */
+ __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
+ __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
+ __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
+ __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
+ __StackBottom = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
+ /* todo assert on extra code */
+}
diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h
new file mode 100644
index 000000000..743151931
--- /dev/null
+++ b/ports/raspberrypi/mpconfigport.h
@@ -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.
+ */
+
+#ifndef __INCLUDED_MPCONFIGPORT_H
+#define __INCLUDED_MPCONFIGPORT_H
+
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define CIRCUITPY_DEFAULT_STACK_SIZE (24*1024)
+
+#define MICROPY_USE_INTERNAL_PRINTF (1)
+
+#define CIRCUITPY_PROCESSOR_COUNT (2)
+
+// This also includes mpconfigboard.h.
+#include "py/circuitpy_mpconfig.h"
+
+#define MICROPY_PORT_ROOT_POINTERS \
+ CIRCUITPY_COMMON_ROOT_POINTERS;
+
+#endif // __INCLUDED_MPCONFIGPORT_H
diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk
new file mode 100644
index 000000000..138896d41
--- /dev/null
+++ b/ports/raspberrypi/mpconfigport.mk
@@ -0,0 +1,47 @@
+# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk
+# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers.
+# This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h.
+
+ifeq ($(LONGINT_IMPL),NONE)
+MPY_TOOL_LONGINT_IMPL = -mlongint-impl=none
+endif
+
+ifeq ($(LONGINT_IMPL),MPZ)
+MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
+endif
+
+ifeq ($(LONGINT_IMPL),LONGLONG)
+MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong
+endif
+
+# All raspberrypi ports have longints.
+LONGINT_IMPL = MPZ
+
+ifndef CIRCUITPY_RP2PIO
+CIRCUITPY_RP2PIO = 1
+else
+CIRCUITPY_NEOPIXEL_WRITE = 0
+endif
+
+CIRCUITPY_FULL_BUILD = 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
+CIRCUITPY_NVM = 0
+CIRCUITPY_PULSEIO = 0 # Use PIO interally
+CIRCUITPY_ROTARYIO = 0 # Use PIO interally
+CIRCUITPY_RTC = 0
+
+# Things that are unsupported by the hardware.
+CIRCUITPY_AUDIOIO = 0
+
+INTERNAL_LIBM = 1
+
+USB_SERIAL_NUMBER_LENGTH = 32
+
+USB_NUM_EP = 8
diff --git a/ports/raspberrypi/mphalport.c b/ports/raspberrypi/mphalport.c
new file mode 100644
index 000000000..89b597bc7
--- /dev/null
+++ b/ports/raspberrypi/mphalport.c
@@ -0,0 +1,57 @@
+/*
+ * 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 <string.h>
+
+#include "lib/mp-readline/readline.h"
+#include "lib/utils/interrupt_char.h"
+#include "py/mphal.h"
+#include "py/mpstate.h"
+#include "py/runtime.h"
+#include "py/smallint.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/time/__init__.h"
+#include "supervisor/shared/autoreload.h"
+
+#include "mpconfigboard.h"
+#include "mphalport.h"
+#include "supervisor/shared/tick.h"
+
+#include "src/rp2_common/hardware_timer/include/hardware/timer.h"
+
+extern uint32_t common_hal_mcu_processor_get_frequency(void);
+
+void mp_hal_delay_us(mp_uint_t delay) {
+ busy_wait_us_32(delay);
+}
+
+void mp_hal_disable_all_interrupts(void) {
+ common_hal_mcu_disable_interrupts();
+}
+
+void mp_hal_enable_all_interrupts(void) {
+ common_hal_mcu_enable_interrupts();
+}
diff --git a/ports/raspberrypi/mphalport.h b/ports/raspberrypi/mphalport.h
new file mode 100644
index 000000000..8d2d7d51a
--- /dev/null
+++ b/ports/raspberrypi/mphalport.h
@@ -0,0 +1,50 @@
+/*
+ * 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_MPHALPORT_H
+#define MICROPY_INCLUDED_RASPBERRYPI_MPHALPORT_H
+
+#include "py/obj.h"
+
+#include "lib/oofatfs/ff.h"
+
+#include "supervisor/shared/tick.h"
+
+// Global millisecond tick count (driven by SysTick interrupt).
+#define mp_hal_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
+
+// Number of bytes in receive buffer
+extern volatile uint8_t usb_rx_count;
+extern volatile bool mp_cdc_enabled;
+
+int receive_usb(void);
+
+void mp_hal_set_interrupt_char(int c);
+
+void mp_hal_disable_all_interrupts(void);
+void mp_hal_enable_all_interrupts(void);
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_MPHALPORT_H
diff --git a/ports/raspberrypi/peripherals/pins.c b/ports/raspberrypi/peripherals/pins.c
new file mode 100644
index 000000000..a2a7b85bd
--- /dev/null
+++ b/ports/raspberrypi/peripherals/pins.c
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the Micro Python 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 "pins.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+
+// This macro is used to simplify pin definition in boards/<board>/pins.c
+#define PIN(p_number) \
+const mcu_pin_obj_t pin_GPIO## p_number = { \
+ { &mcu_pin_type }, \
+ .number = p_number \
+}
+
+PIN(0);
+PIN(1);
+PIN(2);
+PIN(3);
+PIN(4);
+PIN(5);
+PIN(6);
+PIN(7);
+PIN(8);
+PIN(9);
+PIN(10);
+PIN(11);
+PIN(12);
+PIN(13);
+PIN(14);
+PIN(15);
+PIN(16);
+PIN(17);
+PIN(18);
+PIN(19);
+PIN(20);
+PIN(21);
+PIN(22);
+PIN(23);
+PIN(24);
+PIN(25);
+PIN(26);
+PIN(27);
+PIN(28);
+PIN(29);
diff --git a/ports/raspberrypi/peripherals/pins.h b/ports/raspberrypi/peripherals/pins.h
new file mode 100644
index 000000000..99ab9cfe4
--- /dev/null
+++ b/ports/raspberrypi/peripherals/pins.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the Micro Python 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.
+ */
+
+// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
+// that all necessary includes are already included.
+
+#ifndef MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H
+#define MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t number;
+} mcu_pin_obj_t;
+
+extern const mcu_pin_obj_t pin_GPIO0;
+extern const mcu_pin_obj_t pin_GPIO1;
+extern const mcu_pin_obj_t pin_GPIO2;
+extern const mcu_pin_obj_t pin_GPIO3;
+extern const mcu_pin_obj_t pin_GPIO4;
+extern const mcu_pin_obj_t pin_GPIO5;
+extern const mcu_pin_obj_t pin_GPIO6;
+extern const mcu_pin_obj_t pin_GPIO7;
+extern const mcu_pin_obj_t pin_GPIO8;
+extern const mcu_pin_obj_t pin_GPIO9;
+extern const mcu_pin_obj_t pin_GPIO10;
+extern const mcu_pin_obj_t pin_GPIO11;
+extern const mcu_pin_obj_t pin_GPIO12;
+extern const mcu_pin_obj_t pin_GPIO13;
+extern const mcu_pin_obj_t pin_GPIO14;
+extern const mcu_pin_obj_t pin_GPIO15;
+extern const mcu_pin_obj_t pin_GPIO16;
+extern const mcu_pin_obj_t pin_GPIO17;
+extern const mcu_pin_obj_t pin_GPIO18;
+extern const mcu_pin_obj_t pin_GPIO19;
+extern const mcu_pin_obj_t pin_GPIO20;
+extern const mcu_pin_obj_t pin_GPIO21;
+extern const mcu_pin_obj_t pin_GPIO22;
+extern const mcu_pin_obj_t pin_GPIO23;
+extern const mcu_pin_obj_t pin_GPIO24;
+extern const mcu_pin_obj_t pin_GPIO25;
+extern const mcu_pin_obj_t pin_GPIO26;
+extern const mcu_pin_obj_t pin_GPIO27;
+extern const mcu_pin_obj_t pin_GPIO28;
+extern const mcu_pin_obj_t pin_GPIO29;
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H
diff --git a/ports/raspberrypi/qstrdefsport.h b/ports/raspberrypi/qstrdefsport.h
new file mode 100644
index 000000000..3ba897069
--- /dev/null
+++ b/ports/raspberrypi/qstrdefsport.h
@@ -0,0 +1 @@
+// qstrs specific to this port
diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk
new file mode 160000
+Subproject 26653ea81e340cacee55025d110c3e014a252a8
diff --git a/ports/raspberrypi/sdk_config/pico/config_autogen.h b/ports/raspberrypi/sdk_config/pico/config_autogen.h
new file mode 100644
index 000000000..688f367c3
--- /dev/null
+++ b/ports/raspberrypi/sdk_config/pico/config_autogen.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#define PICO_IE_26_29_UNCHANGED_ON_RESET (0)
+#define PICO_USE_STACK_GUARDS (0)
+#define PICO_ENTER_USB_BOOT_ON_EXIT (0)
+#define PICO_USE_OPTIMISTIC_SBRK (0)
+#define PICO_NO_HARDWARE (0)
+#define PICO_ON_DEVICE (1)
+#define PICO_USE_CRT_PRINTF (0)
+#define PICO_NO_PRINTF (0)
+#define PICO_FLOAT_SUPPORT_ROM_V1 (1)
+#define PICO_DOUBLE_SUPPORT_ROM_V1 (1)
+#define PICO_STDIO_UART (0)
+#define PICO_STDIO_USB (0)
+#define PICO_STDIO_SEMIHOSTING (0)
+#define PICO_STDIO_IGNORE_NESTED_STDOUT (0)
+#define PICO_PRINTF_PICO (0)
+#define PICO_PRINTF_NONE (0)
+#define PICO_PRINTF_ALWAYS_INCLUDED (1)
diff --git a/ports/raspberrypi/sdk_config/pico/version.h b/ports/raspberrypi/sdk_config/pico/version.h
new file mode 100644
index 000000000..3a1e1a3d2
--- /dev/null
+++ b/ports/raspberrypi/sdk_config/pico/version.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+// ----------------------------------------------------------
+// THIS FILE IS (NOT) AUTOGENERATED; EDIT when updating sdk/
+// ----------------------------------------------------------
+
+#ifndef _PICO_VERSION_H
+#define _PICO_VERSION_H
+
+#define PICO_SDK_VERSION_MAJOR 1
+#define PICO_SDK_VERSION_MINOR 0
+#define PICO_SDK_VERSION_REVISION 0
+#define PICO_SDK_VERSION_STRING "1.0.0"
+
+#endif
diff --git a/ports/raspberrypi/supervisor/internal_flash.c b/ports/raspberrypi/supervisor/internal_flash.c
new file mode 100644
index 000000000..d333830de
--- /dev/null
+++ b/ports/raspberrypi/supervisor/internal_flash.c
@@ -0,0 +1,131 @@
+/*
+ * 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/internal_flash.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+#include "py/mphal.h"
+#include "py/obj.h"
+#include "py/runtime.h"
+#include "lib/oofatfs/ff.h"
+#include "shared-bindings/microcontroller/__init__.h"
+
+#include "supervisor/usb.h"
+
+#include "src/rp2040/hardware_structs/include/hardware/structs/sio.h"
+#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
+
+// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
+#define SECTOR_SIZE 4096
+#define NO_CACHE 0xffffffff
+STATIC uint8_t _cache[SECTOR_SIZE];
+STATIC uint32_t _cache_lba = NO_CACHE;
+
+void supervisor_flash_init(void) {
+ bi_decl_if_func_used(bi_block_device(
+ BINARY_INFO_MAKE_TAG('C', 'P'),
+ "CircuitPython",
+ RESERVED_FLASH,
+ TOTAL_FLASH_SIZE - RESERVED_FLASH,
+ NULL,
+ BINARY_INFO_BLOCK_DEV_FLAG_READ |
+ BINARY_INFO_BLOCK_DEV_FLAG_WRITE |
+ BINARY_INFO_BLOCK_DEV_FLAG_PT_UNKNOWN));
+}
+
+uint32_t supervisor_flash_get_block_size(void) {
+ return FILESYSTEM_BLOCK_SIZE;
+}
+
+uint32_t supervisor_flash_get_block_count(void) {
+ return (TOTAL_FLASH_SIZE - RESERVED_FLASH) / FILESYSTEM_BLOCK_SIZE;
+}
+
+void port_internal_flash_flush(void) {
+ if (_cache_lba == NO_CACHE) {
+ return;
+ }
+ common_hal_mcu_disable_interrupts();
+ flash_range_erase(RESERVED_FLASH + _cache_lba, SECTOR_SIZE);
+ flash_range_program(RESERVED_FLASH + _cache_lba, _cache, SECTOR_SIZE);
+ common_hal_mcu_enable_interrupts();
+ _cache_lba = NO_CACHE;
+}
+
+mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
+ memcpy(dest,
+ (void*)(XIP_BASE + RESERVED_FLASH + block * FILESYSTEM_BLOCK_SIZE),
+ num_blocks * FILESYSTEM_BLOCK_SIZE);
+ return 0;
+}
+
+mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
+ uint32_t blocks_per_sector = SECTOR_SIZE / FILESYSTEM_BLOCK_SIZE;
+ uint32_t block = 0;
+ while (block < num_blocks) {
+ uint32_t block_address = lba + block;
+ uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE;
+ uint8_t block_offset = block_address % blocks_per_sector;
+
+ if (_cache_lba != block_address) {
+ memcpy(_cache,
+ (void*)(XIP_BASE + RESERVED_FLASH + sector_offset),
+ SECTOR_SIZE);
+ _cache_lba = sector_offset;
+ }
+ for (uint8_t b = block_offset; b < blocks_per_sector; b++) {
+ // Stop copying after the last block.
+ if (block >= num_blocks) {
+ break;
+ }
+ memcpy(_cache + b * FILESYSTEM_BLOCK_SIZE,
+ src + block * FILESYSTEM_BLOCK_SIZE,
+ FILESYSTEM_BLOCK_SIZE);
+ block++;
+ }
+ // Make sure we don't have an interrupt while we do flash operations.
+ common_hal_mcu_disable_interrupts();
+ flash_range_erase(RESERVED_FLASH + sector_offset, SECTOR_SIZE);
+ flash_range_program(RESERVED_FLASH + sector_offset, _cache, SECTOR_SIZE);
+ common_hal_mcu_enable_interrupts();
+ }
+
+ return 0; // success
+}
+
+void supervisor_flash_release_cache(void) {
+}
diff --git a/ports/raspberrypi/supervisor/internal_flash.h b/ports/raspberrypi/supervisor/internal_flash.h
new file mode 100644
index 000000000..0dc9f1545
--- /dev/null
+++ b/ports/raspberrypi/supervisor/internal_flash.h
@@ -0,0 +1,38 @@
+/*
+ * 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_INTERNAL_FLASH_H
+#define MICROPY_INCLUDED_RASPBERRYPI_INTERNAL_FLASH_H
+
+#include <stdbool.h>
+
+#include "mpconfigport.h"
+
+// #define INTERNAL_FLASH_PART1_NUM_BLOCKS (CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE)
+
+// #define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
+// #define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2)
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_INTERNAL_FLASH_H
diff --git a/ports/raspberrypi/supervisor/internal_flash_root_pointers.h b/ports/raspberrypi/supervisor/internal_flash_root_pointers.h
new file mode 100644
index 000000000..419a4c943
--- /dev/null
+++ b/ports/raspberrypi/supervisor/internal_flash_root_pointers.h
@@ -0,0 +1,31 @@
+/*
+ * 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_INTERNAL_FLASH_ROOT_POINTERS_H
+#define MICROPY_INCLUDED_RASPBERRYPI_INTERNAL_FLASH_ROOT_POINTERS_H
+
+#define FLASH_ROOT_POINTERS
+
+#endif // MICROPY_INCLUDED_RASPBERRYPI_INTERNAL_FLASH_ROOT_POINTERS_H
diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c
new file mode 100644
index 000000000..b2f73c7b4
--- /dev/null
+++ b/ports/raspberrypi/supervisor/port.c
@@ -0,0 +1,200 @@
+/*
+ * 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 <string.h>
+#include <stdlib.h>
+
+#include "supervisor/board.h"
+#include "supervisor/port.h"
+
+#include "bindings/rp2pio/StateMachine.h"
+#include "genhdr/mpversion.h"
+#include "shared-bindings/busio/I2C.h"
+#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/rtc/__init__.h"
+#include "shared-bindings/pwmio/PWMOut.h"
+
+#include "supervisor/shared/safe_mode.h"
+#include "supervisor/shared/stack.h"
+#include "supervisor/shared/tick.h"
+
+#include "src/rp2040/hardware_structs/include/hardware/structs/watchdog.h"
+#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
+#include "src/rp2_common/hardware_uart/include/hardware/uart.h"
+#include "src/rp2_common/hardware_sync/include/hardware/sync.h"
+#include "src/rp2_common/hardware_timer/include/hardware/timer.h"
+#include "src/common/pico_time/include/pico/time.h"
+#include "src/common/pico_binary_info/include/pico/binary_info.h"
+
+#include "tusb.h"
+
+
+extern volatile bool mp_msc_enabled;
+
+STATIC void _tick_callback(uint alarm_num);
+
+STATIC void _binary_info(void) {
+ // Binary info readable with `picotool`.
+ bi_decl(bi_program_name("CircuitPython"));
+ bi_decl(bi_program_version_string(MICROPY_GIT_TAG));
+ bi_decl(bi_program_build_date_string(MICROPY_BUILD_DATE));
+ bi_decl(bi_program_url("https://circuitpython.org"));
+
+ bi_decl(bi_program_build_attribute("BOARD=" CIRCUITPY_BOARD_ID));
+ // TODO: Add build attribute for debug builds. Needs newer CircuitPython with CIRCUITPY_DEBUG.
+}
+
+safe_mode_t port_init(void) {
+ _binary_info();
+ // Set brown out.
+
+ // Reset everything into a known state before board_init.
+ reset_port();
+
+ // For the tick.
+ hardware_alarm_claim(0);
+ hardware_alarm_set_callback(0, _tick_callback);
+
+ // Check brownout.
+
+ if (board_requests_safe_mode()) {
+ return USER_SAFE_MODE;
+ }
+
+ return NO_SAFE_MODE;
+}
+
+void reset_port(void) {
+ #if CIRCUITPY_BUSIO
+ reset_i2c();
+ reset_spi();
+ #endif
+
+ #if CIRCUITPY_RP2PIO
+ reset_rp2pio_statemachine();
+ #endif
+
+ #if CIRCUITPY_PWMIO
+ pwmout_reset();
+ #endif
+
+ reset_all_pins();
+}
+
+void reset_to_bootloader(void) {
+ // reset();
+ while (true) {}
+}
+
+void reset_cpu(void) {
+ // reset();
+ while (true) {}
+}
+
+bool port_has_fixed_stack(void) {
+ return false;
+}
+
+// From the linker script
+extern uint32_t __HeapLimit;
+extern uint32_t __StackTop;
+uint32_t *port_stack_get_limit(void) {
+ return &__HeapLimit;
+}
+
+uint32_t *port_stack_get_top(void) {
+ return &__StackTop;
+}
+
+uint32_t *port_heap_get_bottom(void) {
+ return port_stack_get_limit();
+}
+
+uint32_t *port_heap_get_top(void) {
+ return port_stack_get_top();
+}
+
+void port_set_saved_word(uint32_t value) {
+ // NOTE: This doesn't survive pressing the reset button (aka toggling RUN).
+ watchdog_hw->scratch[0] = value;
+}
+
+uint32_t port_get_saved_word(void) {
+ return watchdog_hw->scratch[0];
+}
+
+uint64_t port_get_raw_ticks(uint8_t* subticks) {
+ uint64_t microseconds = time_us_64();
+ return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977;
+}
+
+STATIC void _tick_callback(uint alarm_num) {
+ supervisor_tick();
+ hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977));
+}
+
+// Enable 1/1024 second tick.
+void port_enable_tick(void) {
+ hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977));
+}
+
+// Disable 1/1024 second tick.
+void port_disable_tick(void) {
+ // hardware_alarm_cancel(0);
+}
+
+// This is called by sleep, we ignore it when our ticks are enabled because
+// 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) {
+}
+
+void port_idle_until_interrupt(void) {
+ common_hal_mcu_disable_interrupts();
+ if (!tud_task_event_ready()) {
+// asm volatile ("dsb 0xF":::"memory");
+// __wfi();
+ }
+ common_hal_mcu_enable_interrupts();
+}
+
+/**
+ * \brief Default interrupt handler for unused IRQs.
+ */
+__attribute__((used)) void HardFault_Handler(void)
+{
+#ifdef ENABLE_MICRO_TRACE_BUFFER
+ // Turn off the micro trace buffer so we don't fill it up in the infinite
+ // loop below.
+ REG_MTB_MASTER = 0x00000000 + 6;
+#endif
+
+ reset_into_safe_mode(HARD_CRASH);
+ while (true) {
+ asm("nop;");
+ }
+}
diff --git a/ports/raspberrypi/supervisor/rp2_cpu.s b/ports/raspberrypi/supervisor/rp2_cpu.s
new file mode 100755
index 000000000..741bb2135
--- /dev/null
+++ b/ports/raspberrypi/supervisor/rp2_cpu.s
@@ -0,0 +1,35 @@
+.syntax unified
+.cpu cortex-m0
+.thumb
+.text
+.align 2
+
+@ uint cpu_get_regs_and_sp(r0=uint regs[10])
+.global cpu_get_regs_and_sp
+.thumb
+.thumb_func
+.type cpu_get_regs_and_sp, %function
+cpu_get_regs_and_sp:
+@ store registers into given array
+str r4, [r0, #0]
+str r5, [r0, #4]
+str r6, [r0, #8]
+str r7, [r0, #12]
+push {r1}
+mov r1, r8
+str r1, [r0, #16]
+mov r1, r9
+str r1, [r0, #20]
+mov r1, r10
+str r1, [r0, #24]
+mov r1, r11
+str r1, [r0, #28]
+mov r1, r12
+str r1, [r0, #32]
+mov r1, r13
+str r1, [r0, #36]
+pop {r1}
+
+@ return the sp
+mov r0, sp
+bx lr
diff --git a/ports/raspberrypi/supervisor/usb.c b/ports/raspberrypi/supervisor/usb.c
new file mode 100644
index 000000000..1d2425aed
--- /dev/null
+++ b/ports/raspberrypi/supervisor/usb.c
@@ -0,0 +1,53 @@
+/*
+ * 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 "lib/tinyusb/src/device/usbd.h"
+#include "supervisor/background_callback.h"
+#include "supervisor/usb.h"
+#include "src/rp2_common/hardware_irq/include/hardware/irq.h"
+#include "src/rp2_common/pico_platform/include/pico/platform.h"
+#include "src/rp2040/hardware_regs/include/hardware/regs/intctrl.h"
+
+static background_callback_t usb_callback;
+static void usb_background_do(void* unused) {
+ usb_background();
+}
+
+static void queue_background(void) {
+ background_callback_add(&usb_callback, usb_background_do, NULL);
+}
+
+void init_usb_hardware(void) {
+}
+
+void post_usb_init(void) {
+ irq_handler_t usb_handler = irq_get_exclusive_handler(USBCTRL_IRQ);
+ if (usb_handler) {
+ irq_remove_handler(USBCTRL_IRQ, usb_handler);
+ irq_add_shared_handler(USBCTRL_IRQ, usb_handler, PICO_DEFAULT_IRQ_PRIORITY);
+ }
+ irq_add_shared_handler(USBCTRL_IRQ, queue_background, PICO_LOWEST_IRQ_PRIORITY);
+}
diff --git a/ports/stm/boards/espruino_pico/mpconfigboard.mk b/ports/stm/boards/espruino_pico/mpconfigboard.mk
index 14f9323fd..81c3772e7 100644
--- a/ports/stm/boards/espruino_pico/mpconfigboard.mk
+++ b/ports/stm/boards/espruino_pico/mpconfigboard.mk
@@ -20,5 +20,6 @@ LD_FILE = boards/STM32F401xd_fs.ld
# lto for this port, and if other stuff hasn't been added in the
# meantime
CIRCUITPY_ULAB = 0
+CIRCUITPY_BUSDEVICE = 0
SUPEROPT_GC = 0
diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c b/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c
new file mode 100644
index 000000000..f8e462f93
--- /dev/null
+++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/board.c
@@ -0,0 +1,39 @@
+/*
+ * 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"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.h b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.h
new file mode 100644
index 000000000..65e224e47
--- /dev/null
+++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "stm32f411ce-blackpill-with-flash"
+#define MICROPY_HW_MCU_NAME "STM32F411CE"
+
+#define FLASH_SIZE (0x80000)
+#define FLASH_PAGE_SIZE (0x4000)
+
+#define HSE_VALUE ((uint32_t)25000000)
+#define BOARD_NO_VBUS_SENSE (1)
+#define BOARD_HAS_LOW_SPEED_CRYSTAL (0)
+
+// On-board flash
+#define SPI_FLASH_MOSI_PIN (&pin_PA07)
+#define SPI_FLASH_MISO_PIN (&pin_PA06)
+#define SPI_FLASH_SCK_PIN (&pin_PA05)
+#define SPI_FLASH_CS_PIN (&pin_PA04)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_PB06)
+#define DEFAULT_I2C_BUS_SDA (&pin_PB07)
+
+#define CIRCUITPY_AUTORELOAD_DELAY_MS (500)
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
+
+#define AUTORESET_DELAY_MS (500)
diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk
new file mode 100644
index 000000000..9a95a3539
--- /dev/null
+++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk
@@ -0,0 +1,19 @@
+USB_VID = 0x239A
+USB_PID = 0x006A
+USB_PRODUCT = "stm32f411ce blackpill with flash"
+USB_MANUFACTURER = "Unknown"
+
+SPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 2
+#See supervisor/shared/external_flash/devices.h for options
+EXTERNAL_FLASH_DEVICES = W25Q64FV,W25Q64JV_IQ
+LONGINT_IMPL = MPZ
+
+INTERNAL_FLASH_FILESYSTEM = 0
+
+MCU_SERIES = F4
+MCU_VARIANT = STM32F411xE
+MCU_PACKAGE = UFQFPN48
+
+LD_COMMON = boards/common_default.ld
+LD_FILE = boards/STM32F411_nvm_nofs.ld
diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/pins.c b/ports/stm/boards/stm32f411ce_blackpill_with_flash/pins.c
new file mode 100644
index 000000000..16946b8be
--- /dev/null
+++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/pins.c
@@ -0,0 +1,44 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_B12), MP_ROM_PTR(&pin_PB12) },
+ { MP_ROM_QSTR(MP_QSTR_B13), MP_ROM_PTR(&pin_PB13) },
+ { MP_ROM_QSTR(MP_QSTR_B14), MP_ROM_PTR(&pin_PB14) },
+ { MP_ROM_QSTR(MP_QSTR_B15), MP_ROM_PTR(&pin_PB15) },
+ { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA08) },
+ { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA09) }, //USB (shouldn't be used)
+ { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA10) }, //USB (shouldn't be used)
+ { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PA11) }, //USB (shouldn't be used)
+ { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_PA12) }, //USB (shouldn't be used)
+ { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_PA15) },
+ { MP_ROM_QSTR(MP_QSTR_B3), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_B4), MP_ROM_PTR(&pin_PB04) },
+ { MP_ROM_QSTR(MP_QSTR_B5), MP_ROM_PTR(&pin_PB05) },
+ { MP_ROM_QSTR(MP_QSTR_B6), MP_ROM_PTR(&pin_PB06) },
+ { MP_ROM_QSTR(MP_QSTR_B7), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_B8), MP_ROM_PTR(&pin_PB08) },
+ { MP_ROM_QSTR(MP_QSTR_B9), MP_ROM_PTR(&pin_PB09) },
+
+ { MP_ROM_QSTR(MP_QSTR_B10), MP_ROM_PTR(&pin_PB10) },
+ { MP_ROM_QSTR(MP_QSTR_B2), MP_ROM_PTR(&pin_PB02) },
+ { MP_ROM_QSTR(MP_QSTR_B1), MP_ROM_PTR(&pin_PB01) },
+ { MP_ROM_QSTR(MP_QSTR_B0), MP_ROM_PTR(&pin_PB00) },
+ { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA07) },
+ { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PA06) },
+ { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA05) },
+ { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA04) },
+ { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA03) },
+ { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) },
+ { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) },
+ { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) },
+ { MP_ROM_QSTR(MP_QSTR_C15), MP_ROM_PTR(&pin_PC15) },
+ { MP_ROM_QSTR(MP_QSTR_C14), MP_ROM_PTR(&pin_PC14) },
+ { MP_ROM_QSTR(MP_QSTR_C13), MP_ROM_PTR(&pin_PC13) },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PC13) },
+
+ { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) },
+ { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) },
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/stm/mpconfigport.h b/ports/stm/mpconfigport.h
index 9489b4765..7cdab04f6 100644
--- a/ports/stm/mpconfigport.h
+++ b/ports/stm/mpconfigport.h
@@ -31,9 +31,7 @@
#include <stdint.h>
#define MICROPY_PY_FUNCTION_ATTRS (1)
-#define MICROPY_PY_IO (1)
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
-#define MICROPY_PY_UJSON (1)
extern uint8_t _ld_default_stack_size;
diff --git a/py/builtinhelp.c b/py/builtinhelp.c
index d12e088d6..e1dcb6096 100644
--- a/py/builtinhelp.c
+++ b/py/builtinhelp.c
@@ -152,9 +152,18 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) {
mp_obj_type_t *type = mp_obj_get_type(obj);
// try to print something sensible about the given object
- mp_print_str(MP_PYTHON_PRINTER, "object ");
+ const compressed_string_t* compressed = translate("object ");
+ char decompressed_object[decompress_length(compressed)];
+ decompress(compressed, decompressed_object);
+
+ mp_print_str(MP_PYTHON_PRINTER, decompressed_object);
mp_obj_print(obj, PRINT_STR);
- mp_printf(MP_PYTHON_PRINTER, " is of type %q\n", type->name);
+
+ compressed = translate(" is of type %q\n");
+ char decompressed_typestring[decompress_length(compressed)];
+ decompress(compressed, decompressed_typestring);
+
+ mp_printf(MP_PYTHON_PRINTER, decompressed_typestring, type->name);
mp_map_t *map = NULL;
if (type == &mp_type_module) {
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 21bd5b965..3ce7c0117 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -51,6 +51,7 @@ BASE_CFLAGS = \
-DCIRCUITPY_SOFTWARE_SAFE_MODE=0x0ADABEEF \
-DCIRCUITPY_CANARY_WORD=0xADAF00 \
-DCIRCUITPY_SAFE_RESTART_WORD=0xDEADBEEF \
+ -DCIRCUITPY_BOARD_ID="\"$(BOARD)\"" \
--param max-inline-insns-single=500
# Use these flags to debug build times and header includes.
@@ -234,6 +235,9 @@ endif
ifeq ($(CIRCUITPY_RANDOM),1)
SRC_PATTERNS += random/%
endif
+ifeq ($(CIRCUITPY_RP2PIO),1)
+SRC_PATTERNS += rp2pio/%
+endif
ifeq ($(CIRCUITPY_ROTARYIO),1)
SRC_PATTERNS += rotaryio/%
endif
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index a3411b7ad..ee23c7156 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -195,21 +195,12 @@ typedef long mp_off_t;
#define MICROPY_PY_BUILTINS_STR_CENTER (CIRCUITPY_FULL_BUILD)
#define MICROPY_PY_BUILTINS_STR_PARTITION (CIRCUITPY_FULL_BUILD)
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (CIRCUITPY_FULL_BUILD)
-#define MICROPY_PY_UERRNO (CIRCUITPY_FULL_BUILD)
#ifndef MICROPY_PY_COLLECTIONS_ORDEREDDICT
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (CIRCUITPY_FULL_BUILD)
#endif
-#ifndef MICROPY_PY_UBINASCII
-#define MICROPY_PY_UBINASCII (CIRCUITPY_FULL_BUILD)
-#endif
-// Opposite setting is deliberate.
-#define MICROPY_PY_UERRNO_ERRORCODE (!CIRCUITPY_FULL_BUILD)
-#ifndef MICROPY_PY_URE
-#define MICROPY_PY_URE (CIRCUITPY_FULL_BUILD)
-#endif
-#define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_FULL_BUILD)
-#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_FULL_BUILD)
-#define MICROPY_PY_URE_SUB (CIRCUITPY_FULL_BUILD)
+#define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_RE)
+#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_RE)
+#define MICROPY_PY_URE_SUB (CIRCUITPY_RE)
// LONGINT_IMPL_xxx are defined in the Makefile.
//
@@ -228,7 +219,7 @@ typedef long mp_off_t;
#endif
#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS
-#define MICROPY_PY_REVERSE_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD)
+#define MICROPY_PY_REVERSE_SPECIAL_METHODS (CIRCUITPY_ULAB || CIRCUITPY_FULL_BUILD)
#endif
#if INTERNAL_FLASH_FILESYSTEM == 0 && QSPI_FLASH_FILESYSTEM == 0 && SPI_FLASH_FILESYSTEM == 0 && !DISABLE_FILESYSTEM
@@ -301,6 +292,13 @@ extern const struct _mp_obj_module_t audiopwmio_module;
#define AUDIOPWMIO_MODULE
#endif
+#if CIRCUITPY_BINASCII
+#define MICROPY_PY_UBINASCII CIRCUITPY_BINASCII
+#define BINASCII_MODULE { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) },
+#else
+#define BINASCII_MODULE
+#endif
+
#if CIRCUITPY_BITBANGIO
#define BITBANGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module },
extern const struct _mp_obj_module_t bitbangio_module;
@@ -399,6 +397,16 @@ extern const struct _mp_obj_module_t terminalio_module;
#define TERMINALIO_MODULE
#endif
+#if CIRCUITPY_ERRNO
+#define MICROPY_PY_UERRNO (1)
+// Uses about 80 bytes.
+#define MICROPY_PY_UERRNO_ERRORCODE (1)
+#define ERRNO_MODULE { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) },
+#else
+#define ERRNO_MODULE
+#
+#endif
+
#if CIRCUITPY_ESPIDF
extern const struct _mp_obj_module_t espidf_module;
#define ESPIDF_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_espidf),(mp_obj_t)&espidf_module },
@@ -470,6 +478,18 @@ extern const struct _mp_obj_module_t ipaddress_module;
#define IPADDRESS_MODULE
#endif
+#if CIRCUITPY_JSON
+#define MICROPY_PY_UJSON (1)
+#define MICROPY_PY_IO (1)
+#define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) },
+#else
+#ifndef MICROPY_PY_IO
+// We don't need MICROPY_PY_IO unless someone else wants it.
+#define MICROPY_PY_IO (0)
+#endif
+#define JSON_MODULE
+#endif
+
#if CIRCUITPY_MATH
extern const struct _mp_obj_module_t math_module;
#define MATH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module },
@@ -581,13 +601,6 @@ extern const struct _mp_obj_module_t pwmio_module;
#define PWMIO_MODULE
#endif
-#if CIRCUITPY_RGBMATRIX
-extern const struct _mp_obj_module_t rgbmatrix_module;
-#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module },
-#else
-#define RGBMATRIX_MODULE
-#endif
-
#if CIRCUITPY_RANDOM
extern const struct _mp_obj_module_t random_module;
#define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module },
@@ -595,6 +608,20 @@ extern const struct _mp_obj_module_t random_module;
#define RANDOM_MODULE
#endif
+#if CIRCUITPY_RE
+#define MICROPY_PY_URE (1)
+#define RE_MODULE { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) },
+#else
+#define RE_MODULE
+#endif
+
+#if CIRCUITPY_RGBMATRIX
+extern const struct _mp_obj_module_t rgbmatrix_module;
+#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module },
+#else
+#define RGBMATRIX_MODULE
+#endif
+
#if CIRCUITPY_ROTARYIO
extern const struct _mp_obj_module_t rotaryio_module;
#define ROTARYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module },
@@ -602,6 +629,13 @@ extern const struct _mp_obj_module_t rotaryio_module;
#define ROTARYIO_MODULE
#endif
+#if CIRCUITPY_RP2PIO
+extern const struct _mp_obj_module_t rp2pio_module;
+#define RP2PIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rp2pio),(mp_obj_t)&rp2pio_module },
+#else
+#define RP2PIO_MODULE
+#endif
+
#if CIRCUITPY_RTC
extern const struct _mp_obj_module_t rtc_module;
#define RTC_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rtc), (mp_obj_t)&rtc_module },
@@ -723,25 +757,6 @@ extern const struct _mp_obj_module_t ustack_module;
#define USTACK_MODULE
#endif
-// These modules are not yet in shared-bindings, but we prefer the non-uxxx names.
-#if MICROPY_PY_UBINASCII
-#define BINASCII_MODULE { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) },
-#else
-#define BINASCII_MODULE
-#endif
-
-#if MICROPY_PY_UERRNO
-#define ERRNO_MODULE { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) },
-#else
-#define ERRNO_MODULE
-#endif
-
-#if MICROPY_PY_UJSON
-#define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) },
-#else
-#define JSON_MODULE
-#endif
-
#if defined(CIRCUITPY_ULAB) && CIRCUITPY_ULAB
// ulab requires reverse special methods
#if defined(MICROPY_PY_REVERSE_SPECIAL_METHODS) && !MICROPY_PY_REVERSE_SPECIAL_METHODS
@@ -753,12 +768,6 @@ extern const struct _mp_obj_module_t ustack_module;
#define ULAB_MODULE
#endif
-#if MICROPY_PY_URE
-#define RE_MODULE { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) },
-#else
-#define RE_MODULE
-#endif
-
// This is not a top-level module; it's microcontroller.watchdog.
#if CIRCUITPY_WATCHDOG
extern const struct _mp_obj_module_t watchdog_module;
@@ -852,6 +861,7 @@ extern const struct _mp_obj_module_t msgpack_module;
RE_MODULE \
RGBMATRIX_MODULE \
ROTARYIO_MODULE \
+ RP2PIO_MODULE \
RTC_MODULE \
SAMD_MODULE \
SDCARDIO_MODULE \
@@ -928,12 +938,15 @@ void supervisor_run_background_tasks_if_tick(void);
#define CIRCUITPY_PYSTACK_SIZE 1536
#endif
-
// Wait this long imediately after startup to see if we are connected to USB.
#ifndef CIRCUITPY_USB_CONNECTED_SLEEP_DELAY
#define CIRCUITPY_USB_CONNECTED_SLEEP_DELAY 5
#endif
+#ifndef CIRCUITPY_PROCESSOR_COUNT
+#define CIRCUITPY_PROCESSOR_COUNT (1)
+#endif
+
#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt"
#define CIRCUITPY_VERBOSE_BLE 0
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index d0145a90f..b8fe73eea 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -86,6 +86,9 @@ endif
endif
CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3)
+CIRCUITPY_BINASCII ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_BINASCII=$(CIRCUITPY_BINASCII)
+
CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO)
@@ -100,7 +103,7 @@ CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
-CIRCUITPY_BUSDEVICE = 0
+CIRCUITPY_BUSDEVICE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BUSDEVICE=$(CIRCUITPY_BUSDEVICE)
CIRCUITPY_BUILTINS_POW3 ?= $(CIRCUITPY_FULL_BUILD)
@@ -124,6 +127,9 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
+CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO)
+
# CIRCUITPY_ESPIDF is handled in the esp32s2 tree.
# Only for ESP32S chips.
# Assume not a ESP build.
@@ -158,6 +164,9 @@ CFLAGS += -DCIRCUITPY_I2CPERIPHERAL=$(CIRCUITPY_I2CPERIPHERAL)
CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI)
CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS)
+CIRCUITPY_JSON ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_JSON=$(CIRCUITPY_JSON)
+
CIRCUITPY_MATH ?= 1
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
@@ -198,12 +207,21 @@ CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO)
# For now we tie PWMIO to PULSEIO so they always both exist. In CircuitPython 7
# we can enable and disable them separately once PWMOut is removed from `pulseio`.
-CIRCUITPY_PWMIO = $(CIRCUITPY_PULSEIO)
+CIRCUITPY_PWMIO ?= $(CIRCUITPY_PULSEIO)
CFLAGS += -DCIRCUITPY_PWMIO=$(CIRCUITPY_PWMIO)
CIRCUITPY_RANDOM ?= 1
CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
+CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE)
+
+# CIRCUITPY_RP2PIO is handled in the raspberrypi tree.
+# Only for rp2 chips.
+# Assume not a rp2 build.
+CIRCUITPY_RP2PIO ?= 0
+CFLAGS += -DCIRCUITPY_RP2PIO=$(CIRCUITPY_RP2PIO)
+
CIRCUITPY_RGBMATRIX ?= 0
CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c
index 0f628b6fb..c043aa5fa 100644
--- a/shared-bindings/_eve/__init__.c
+++ b/shared-bindings/_eve/__init__.c
@@ -604,22 +604,6 @@ STATIC mp_obj_t _jump(mp_obj_t self, mp_obj_t a0) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(jump_obj, _jump);
-//| def LineWidth(self, width: int) -> None:
-//| """Set the width of rasterized lines
-//|
-//| :param int width: line width in :math:`1/16` pixel. Range 0-4095. The initial value is 16
-//|
-//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
-//| ...
-//|
-
-STATIC mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) {
- uint32_t width = mp_obj_get_int_truncated(a0);
- common_hal__eve_LineWidth(EVEHAL(self), width);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth);
-
//| def Macro(self, m: int) -> None:
//| """Execute a single command from a macro register
//|
@@ -662,22 +646,6 @@ STATIC mp_obj_t _palettesource(mp_obj_t self, mp_obj_t a0) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(palettesource_obj, _palettesource);
-//| def PointSize(self, size: int) -> None:
-//| """Set the radius of rasterized points
-//|
-//| :param int size: point radius in :math:`1/16` pixel. Range 0-8191. The initial value is 16
-//|
-//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
-//| ...
-//|
-
-STATIC mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) {
- uint32_t size = mp_obj_get_int_truncated(a0);
- common_hal__eve_PointSize(EVEHAL(self), size);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize);
-
//| def RestoreContext(self) -> None:
//| """Restore the current graphics context from the context stack"""
//| ...
@@ -836,48 +804,6 @@ STATIC mp_obj_t _tag(mp_obj_t self, mp_obj_t a0) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(tag_obj, _tag);
-//| def VertexTranslateX(self, x: int) -> None:
-//| """Set the vertex transformation's x translation component
-//|
-//| :param int x: signed x-coordinate in :math:`1/16` pixel. Range 0-131071. The initial value is 0
-//|
-//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
-//| ...
-//|
-
-STATIC mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) {
- uint32_t x = mp_obj_get_int_truncated(a0);
- common_hal__eve_VertexTranslateX(EVEHAL(self), x);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex);
-
-//| def VertexTranslateY(self, y: int) -> None:
-//| """Set the vertex transformation's y translation component
-//|
-//| :param int y: signed y-coordinate in :math:`1/16` pixel. Range 0-131071. The initial value is 0
-//|
-//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
-//| ...
-//|
-
-
-STATIC mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) {
- uint32_t y = mp_obj_get_int_truncated(a0);
- common_hal__eve_VertexTranslateY(EVEHAL(self), y);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey);
-
-//| def VertexFormat(self, frac: int) -> None:
-//| """Set the precision of vertex2f coordinates
-//|
-//| :param int frac: Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The initial value is 4
-//|
-//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
-//| ...
-//|
-
STATIC mp_obj_t _vertexformat(mp_obj_t self, mp_obj_t a0) {
uint32_t frac = mp_obj_get_int_truncated(a0);
common_hal__eve_VertexFormat(EVEHAL(self), frac);
@@ -975,6 +901,82 @@ STATIC mp_obj_t _vertex2f(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f);
+//| def LineWidth(self, width: float) -> None:
+//| """Set the width of rasterized lines
+//|
+//| :param float width: line width in pixels. Range 0-511. The initial value is 1
+//|
+//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
+//| ...
+//|
+
+STATIC mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) {
+ mp_float_t width = mp_obj_get_float(a0);
+ common_hal__eve_LineWidth(EVEHAL(self), width);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth);
+
+//| def PointSize(self, size: float) -> None:
+//| """Set the diameter of rasterized points
+//|
+//| :param float size: point diameter in pixels. Range 0-1023. The initial value is 1
+//|
+//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
+//| ...
+//|
+
+STATIC mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) {
+ mp_float_t size = mp_obj_get_float(a0);
+ common_hal__eve_PointSize(EVEHAL(self), size);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize);
+
+//| def VertexTranslateX(self, x: float) -> None:
+//| """Set the vertex transformation's x translation component
+//|
+//| :param float x: signed x-coordinate in pixels. Range ±4095. The initial value is 0
+//|
+//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
+//| ...
+//|
+
+STATIC mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) {
+ mp_float_t x = mp_obj_get_float(a0);
+ common_hal__eve_VertexTranslateX(EVEHAL(self), x);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex);
+
+//| def VertexTranslateY(self, y: float) -> None:
+//| """Set the vertex transformation's y translation component
+//|
+//| :param float y: signed y-coordinate in pixels. Range ±4095. The initial value is 0
+//|
+//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
+//| ...
+//|
+
+
+STATIC mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) {
+ mp_float_t y = mp_obj_get_float(a0);
+ common_hal__eve_VertexTranslateY(EVEHAL(self), y);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey);
+
+//| def VertexFormat(self, frac: int) -> None:
+//| """Set the precision of vertex2f coordinates
+//|
+//| :param int frac: Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The initial value is 4
+//|
+//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`."""
+//| ...
+//|
+
+//}
+
// Append an object x to the FIFO
#define ADD_X(self, x) \
common_hal__eve_add(EVEHAL(self), sizeof(x), &(x));
diff --git a/shared-bindings/_eve/__init__.h b/shared-bindings/_eve/__init__.h
index 759a629bb..883b1a15b 100644
--- a/shared-bindings/_eve/__init__.h
+++ b/shared-bindings/_eve/__init__.h
@@ -61,11 +61,11 @@ void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t gre
void common_hal__eve_Display(common_hal__eve_t *eve);
void common_hal__eve_End(common_hal__eve_t *eve);
void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest);
-void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width);
+void common_hal__eve_LineWidth(common_hal__eve_t *eve, mp_float_t width);
void common_hal__eve_Macro(common_hal__eve_t *eve, uint32_t m);
void common_hal__eve_Nop(common_hal__eve_t *eve);
void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr);
-void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size);
+void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size);
void common_hal__eve_RestoreContext(common_hal__eve_t *eve);
void common_hal__eve_Return(common_hal__eve_t *eve);
void common_hal__eve_SaveContext(common_hal__eve_t *eve);
@@ -76,8 +76,8 @@ void common_hal__eve_StencilMask(common_hal__eve_t *eve, uint32_t mask);
void common_hal__eve_StencilOp(common_hal__eve_t *eve, uint32_t sfail, uint32_t spass);
void common_hal__eve_TagMask(common_hal__eve_t *eve, uint32_t mask);
void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s);
-void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x);
-void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y);
+void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, mp_float_t x);
+void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, mp_float_t y);
void common_hal__eve_VertexFormat(common_hal__eve_t *eve, uint32_t frac);
void common_hal__eve_Vertex2ii(common_hal__eve_t *eve, uint32_t x, uint32_t y, uint32_t handle, uint32_t cell);
diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/I2CDevice.c
index a4c04e198..15e8cc706 100644
--- a/shared-bindings/adafruit_bus_device/I2CDevice.c
+++ b/shared-bindings/adafruit_bus_device/I2CDevice.c
@@ -76,7 +76,7 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type
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);
- busio_i2c_obj_t* i2c = args[ARG_i2c].u_obj;
+ mp_obj_t* i2c = args[ARG_i2c].u_obj;
common_hal_adafruit_bus_device_i2cdevice_construct(MP_OBJ_TO_PTR(self), i2c, args[ARG_device_address].u_int);
if (args[ARG_probe].u_bool == true) {
@@ -107,7 +107,7 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit___obj, 4, 4, adafruit_bus_device_i2cdevice_obj___exit__);
-//| def readinto(self, buf: WriteableBuffer, *, start: int = 0, end: int = 0) -> None:
+//| def readinto(self, buf: WriteableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
//| """Read into ``buf`` from the device. The number of bytes read will be the
//| length of ``buf``.
//| If ``start`` or ``end`` is provided, then the buffer will be sliced
@@ -118,22 +118,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit_
//| :param int end: Index to write up to but not include; if None, use ``len(buf)``"""
//| ...
//|
-STATIC void readinto(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, int32_t start, mp_int_t end) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE);
-
- size_t length = bufinfo.len;
- normalize_buffer_bounds(&start, end, &length);
- if (length == 0) {
- mp_raise_ValueError(translate("Buffer must be at least length 1"));
- }
-
- uint8_t status = common_hal_adafruit_bus_device_i2cdevice_readinto(MP_OBJ_TO_PTR(self), ((uint8_t*)bufinfo.buf) + start, length);
- if (status != 0) {
- mp_raise_OSError(status);
- }
-}
-
STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
static const mp_arg_t allowed_args[] = {
@@ -147,12 +131,22 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_o
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- readinto(self, args[ARG_buffer].u_obj, args[ARG_start].u_int, args[ARG_end].u_int);
+ mp_obj_t dest[8];
+ mp_load_method(self->i2c, MP_QSTR_readfrom_into, dest);
+ dest[2] = mp_obj_new_int_from_ull(self->device_address);
+ dest[3] = args[ARG_buffer].u_obj;
+ //dest[4] = mp_obj_new_str("start", 5);
+ dest[4] = MP_OBJ_NEW_QSTR(MP_QSTR_start);
+ dest[5] = mp_obj_new_int(args[ARG_start].u_int);
+ dest[6] = MP_OBJ_NEW_QSTR(MP_QSTR_end);
+ dest[7] = mp_obj_new_int(args[ARG_end].u_int);
+ mp_call_method_n_kw(2, 2, dest);
+
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 2, adafruit_bus_device_i2cdevice_readinto);
-//| def write(self, buf: ReadableBuffer, *, start: int = 0, end: int = 0) -> None:
+//| def write(self, buf: ReadableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
//| """Write the bytes from ``buffer`` to the device, then transmit a stop bit.
//| If ``start`` or ``end`` is provided, then the buffer will be sliced
//| as if ``buffer[start:end]``. This will not cause an allocation like
@@ -163,22 +157,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 2,
//| """
//| ...
//|
-STATIC void write(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, int32_t start, mp_int_t end, bool transmit_stop_bit) {
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ);
-
- size_t length = bufinfo.len;
- normalize_buffer_bounds(&start, end, &length);
- if (length == 0) {
- mp_raise_ValueError(translate("Buffer must be at least length 1"));
- }
-
- uint8_t status = common_hal_adafruit_bus_device_i2cdevice_write(MP_OBJ_TO_PTR(self), ((uint8_t*)bufinfo.buf) + start, length, transmit_stop_bit);
- if (status != 0) {
- mp_raise_OSError(status);
- }
-}
-
STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
static const mp_arg_t allowed_args[] = {
@@ -191,13 +169,22 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- write(self, args[ARG_buffer].u_obj, args[ARG_start].u_int, args[ARG_end].u_int, true);
+ mp_obj_t dest[8];
+ mp_load_method(self->i2c, MP_QSTR_writeto, dest);
+ dest[2] = mp_obj_new_int_from_ull(self->device_address);
+ dest[3] = args[ARG_buffer].u_obj;
+ dest[4] = MP_OBJ_NEW_QSTR(MP_QSTR_start);
+ dest[5] = mp_obj_new_int(args[ARG_start].u_int);
+ dest[6] = MP_OBJ_NEW_QSTR(MP_QSTR_end);
+ dest[7] = mp_obj_new_int(args[ARG_end].u_int);
+ mp_call_method_n_kw(2, 2, dest);
+
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 2, adafruit_bus_device_i2cdevice_write);
-//| def write_then_readinto(self, out_buffer: WriteableBuffer, in_buffer: ReadableBuffer, *, out_start: int = 0, out_end: int = 0, in_start: int = 0, in_end: int = 0) -> None:
+//| def write_then_readinto(self, out_buffer: WriteableBuffer, in_buffer: ReadableBuffer, *, out_start: int = 0, out_end: Optional[int] = None, in_start: int = 0, in_end: Optional[int] = None) -> None:
//| """Write the bytes from ``out_buffer`` to the device, then immediately
//| reads into ``in_buffer`` from the device. The number of bytes read
//| will be the length of ``in_buffer``.
@@ -233,9 +220,21 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write_then_readinto(size_t n_args,
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- write(self, args[ARG_out_buffer].u_obj, args[ARG_out_start].u_int, args[ARG_out_end].u_int, false);
-
- readinto(self, args[ARG_in_buffer].u_obj, args[ARG_in_start].u_int, args[ARG_in_end].u_int);
+ mp_obj_t dest[13];
+ mp_load_method(self->i2c, MP_QSTR_writeto_then_readfrom, dest);
+ dest[2] = mp_obj_new_int_from_ull(self->device_address);
+ dest[3] = args[ARG_out_buffer].u_obj;
+ dest[4] = args[ARG_in_buffer].u_obj;
+ dest[5] = MP_OBJ_NEW_QSTR(MP_QSTR_out_start);
+ dest[6] = mp_obj_new_int(args[ARG_out_start].u_int);
+ dest[7] = MP_OBJ_NEW_QSTR(MP_QSTR_out_end);
+ dest[8] = mp_obj_new_int(args[ARG_out_end].u_int);
+ dest[9] = MP_OBJ_NEW_QSTR(MP_QSTR_in_start);
+ dest[10] = mp_obj_new_int(args[ARG_in_start].u_int);
+ dest[11] = MP_OBJ_NEW_QSTR(MP_QSTR_in_end);
+ dest[12] = mp_obj_new_int(args[ARG_in_end].u_int);
+
+ mp_call_method_n_kw(3, 4, dest);
return mp_const_none;
}
diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.h b/shared-bindings/adafruit_bus_device/I2CDevice.h
index cf7b1321a..82ef1feb8 100644
--- a/shared-bindings/adafruit_bus_device/I2CDevice.h
+++ b/shared-bindings/adafruit_bus_device/I2CDevice.h
@@ -43,9 +43,7 @@
extern const mp_obj_type_t adafruit_bus_device_i2cdevice_type;
// Initializes the hardware peripheral.
-extern void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, busio_i2c_obj_t *i2c, uint8_t device_address);
-extern uint8_t common_hal_adafruit_bus_device_i2cdevice_readinto(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length);
-extern uint8_t common_hal_adafruit_bus_device_i2cdevice_write(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length, bool transmit_stop_bit);
+extern void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t *i2c, uint8_t device_address);
extern void common_hal_adafruit_bus_device_i2cdevice_lock(adafruit_bus_device_i2cdevice_obj_t *self);
extern void common_hal_adafruit_bus_device_i2cdevice_unlock(adafruit_bus_device_i2cdevice_obj_t *self);
extern void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_device_i2cdevice_obj_t *self);
diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c
index 6ba02a0e7..2a97b54b3 100644
--- a/shared-bindings/microcontroller/Pin.c
+++ b/shared-bindings/microcontroller/Pin.c
@@ -66,12 +66,12 @@ static void get_pin_name(const mcu_pin_obj_t *self, qstr* package, qstr* module,
STATIC void mcu_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mcu_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- qstr package;
+ qstr package = MP_QSTR_Pin;
qstr module;
- qstr name;
+ qstr name = MP_QSTR_Pin;
get_pin_name(self, &package, &module, &name);
- if (package){
+ if (package) {
mp_printf(print, "%q.%q.%q", package, module, name);
} else {
mp_printf(print, "%q.%q", module , name);
@@ -131,7 +131,7 @@ void assert_pin_free(const mcu_pin_obj_t* pin) {
if (pin != NULL && pin != MP_OBJ_TO_PTR(mp_const_none) && !common_hal_mcu_pin_is_free(pin)) {
qstr package;
qstr module;
- qstr name;
+ qstr name = MP_QSTR_Pin;
get_pin_name(pin, &package, &module, &name);
mp_raise_ValueError_varg(translate("%q in use"), name);
diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h
index 0dafc74c7..39d3e718b 100644
--- a/shared-bindings/microcontroller/__init__.h
+++ b/shared-bindings/microcontroller/__init__.h
@@ -29,6 +29,7 @@
#include "py/obj.h"
#include "py/mpconfig.h"
+#include "py/objtuple.h"
#include "common-hal/microcontroller/Processor.h"
#include "shared-bindings/microcontroller/ResetReason.h"
@@ -44,7 +45,13 @@ extern void common_hal_mcu_reset(void);
extern const mp_obj_dict_t mcu_pin_globals;
+#if CIRCUITPY_PROCESSOR_COUNT == 1
extern const mcu_processor_obj_t common_hal_mcu_processor_obj;
+#elif CIRCUITPY_PROCESSOR_COUNT > 1
+extern const mp_rom_obj_tuple_t common_hal_mcu_processor_obj;
+#else
+#error "Invalid processor count"
+#endif
#if CIRCUITPY_INTERNAL_NVM_SIZE > 0
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c
index 5f5ea4fae..2a81bb53c 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.c
+++ b/shared-bindings/rgbmatrix/RGBMatrix.c
@@ -132,11 +132,11 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
}
}
-//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0) -> None:
+//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0, tile: int = 1, serpentine: bool = False) -> None:
//| """Create a RGBMatrix object with the given attributes. The height of
-//| the display is determined by the number of rgb and address pins:
-//| len(rgb_pins) // 3 * 2 ** len(address_pins). With 6 RGB pins and 4
-//| address lines, the display will be 32 pixels tall. If the optional height
+//| the display is determined by the number of rgb and address pins and the number of tiles:
+//| ``len(rgb_pins) // 3 * 2 ** len(address_pins) * abs(tile)``. With 6 RGB pins, 4
+//| address lines, and a single matrix, the display will be 32 pixels tall. If the optional height
//| parameter is specified and is not 0, it is checked against the calculated
//| height.
//|
@@ -172,7 +172,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list,
- ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height };
+ ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height, ARG_tile, ARG_serpentine };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
{ MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
@@ -184,6 +184,8 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
{ MP_QSTR_doublebuffer, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = true } },
{ MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } },
+ { MP_QSTR_tile, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 1 } },
+ { MP_QSTR_serpentine, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -210,12 +212,18 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
mp_raise_ValueError_varg(translate("Must use a multiple of 6 rgb pins, not %d"), rgb_count);
}
- // TODO(@jepler) Use fewer than all rows of pixels if height < computed_height
+ int tile = args[ARG_tile].u_int;
+
+ if (tile <= 0) {
+ mp_raise_ValueError_varg(
+ translate("tile must be greater than zero"));
+ }
+
+ int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile;
if (args[ARG_height].u_int != 0) {
- int computed_height = (rgb_count / 3) << (addr_count);
if (computed_height != args[ARG_height].u_int) {
mp_raise_ValueError_varg(
- translate("%d address pins and %d rgb pins indicate a height of %d, not %d"), addr_count, rgb_count, computed_height, args[ARG_height].u_int);
+ translate("%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"), addr_count, rgb_count, tile, computed_height, args[ARG_height].u_int);
}
}
@@ -228,7 +236,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
if (framebuffer == mp_const_none) {
int width = args[ARG_width].u_int;
- int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count);
+ int bufsize = 2 * width * computed_height;
framebuffer = mp_obj_new_bytearray_of_zeros(bufsize);
}
@@ -239,7 +247,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
addr_count, addr_pins,
clock_pin, latch_pin, output_enable_pin,
args[ARG_doublebuffer].u_bool,
- framebuffer, NULL);
+ framebuffer, tile, args[ARG_serpentine].u_bool, NULL);
claim_and_never_reset_pins(args[ARG_rgb_list].u_obj);
claim_and_never_reset_pins(args[ARG_addr_list].u_obj);
diff --git a/shared-bindings/rgbmatrix/RGBMatrix.h b/shared-bindings/rgbmatrix/RGBMatrix.h
index bfe37c340..4eb3c04b2 100644
--- a/shared-bindings/rgbmatrix/RGBMatrix.h
+++ b/shared-bindings/rgbmatrix/RGBMatrix.h
@@ -31,7 +31,7 @@
extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
-void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer);
+void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void* timer);
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*);
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t*);
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer);
diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c
index 0e6968d5f..007417340 100644
--- a/shared-bindings/socketpool/Socket.c
+++ b/shared-bindings/socketpool/Socket.c
@@ -64,94 +64,65 @@ STATIC mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args)
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, socketpool_socket___exit__);
-// //| def bind(self, address: tuple) -> None:
-// //| """Bind a socket to an address
-// //|
-// //| :param ~tuple address: tuple of (remote_address, remote_port)"""
-// //| ...
-// //|
-
-// STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
-// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
-// // // get address
-// // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
-// // mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
-
-// // // check if we need to select a NIC
-// // socket_select_nic(self, ip);
-
-// // // call the NIC to bind the socket
-// // int _errno;
-// // if (self->nic_type->bind(self, ip, port, &_errno) != 0) {
-// // mp_raise_OSError(_errno);
-// // }
-
-// return mp_const_none;
-// }
-// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_bind);
-
-// //| def listen(self, backlog: int) -> None:
-// //| """Set socket to listen for incoming connections
-// //|
-// //| :param ~int backlog: length of backlog queue for waiting connetions"""
-// //| ...
-// //|
-
-// STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
-// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
+//| def bind(self, address: Tuple[str, int]) -> None:
+//| """Bind a socket to an address
+//|
+//| :param ~tuple address: tuple of (remote_address, remote_port)"""
+//| ...
+//|
+STATIC mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
+ socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
-// // if (self->nic == MP_OBJ_NULL) {
-// // // not connected
-// // // TODO I think we can listen even if not bound...
-// // mp_raise_OSError(MP_ENOTCONN);
-// // }
+ mp_obj_t *addr_items;
+ mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
-// // int _errno;
-// // if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) {
-// // mp_raise_OSError(_errno);
-// // }
+ 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]);
-// return mp_const_none;
-// }
-// STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket_listen);
+ bool ok = common_hal_socketpool_socket_bind(self, host, hostlen, port);
+ if (!ok) {
+ mp_raise_ValueError(translate("Error: Failure to bind"));
+ }
-// //| def accept(self) -> tuple:
-// //| """Accept a connection on a listening socket of type SOCK_STREAM,
-// //| creating a new socket of type SOCK_STREAM.
-// //| Returns a tuple of (new_socket, remote_address)"""
-// //|
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_bind);
-// STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) {
-// // mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
+//| def listen(self, backlog: int) -> None:
+//| """Set socket to listen for incoming connections
+//|
+//| :param ~int backlog: length of backlog queue for waiting connetions"""
+//| ...
+//|
+STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) {
+ socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
-// // // create new socket object
-// // // starts with empty NIC so that finaliser doesn't run close() method if accept() fails
-// // mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
-// // socket2->base.type = &socket_type;
-// // socket2->nic = MP_OBJ_NULL;
-// // socket2->nic_type = NULL;
+ int backlog = mp_obj_get_int(backlog_in);
-// // // accept incoming connection
-// // uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
-// // mp_uint_t port;
-// // int _errno;
-// // if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) {
-// // mp_raise_OSError(_errno);
-// // }
+ common_hal_socketpool_socket_listen(self, backlog);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket_listen);
-// // // new socket has valid state, so set the NIC to the same as parent
-// // socket2->nic = self->nic;
-// // socket2->nic_type = self->nic_type;
+//| def accept(self) -> Tuple[Socket, Tuple[str, int]]:
+//| """Accept a connection on a listening socket of type SOCK_STREAM,
+//| creating a new socket of type SOCK_STREAM.
+//| Returns a tuple of (new_socket, remote_address)"""
+//|
+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;
-// // // make the return value
-// // mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
-// // client->items[0] = MP_OBJ_FROM_PTR(socket2);
-// // client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
+ socketpool_socket_obj_t * sock = common_hal_socketpool_socket_accept(self, ip, &port);
-// return mp_const_none;
-// }
-// STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept);
+ mp_obj_t tuple_contents[2];
+ tuple_contents[0] = MP_OBJ_FROM_PTR(sock);
+ tuple_contents[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
+ return mp_obj_new_tuple(2, tuple_contents);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept);
//| def close(self) -> None:
//| """Closes this Socket and makes its resources available to its SocketPool."""
@@ -169,7 +140,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_
//| :param ~tuple address: tuple of (remote_address, remote_port)"""
//| ...
//|
-
STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -196,7 +166,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke
//| :param ~bytes bytes: some bytes to send"""
//| ...
//|
-
STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (common_hal_socketpool_socket_get_closed(self)) {
@@ -216,19 +185,6 @@ STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_send);
-
-// helper function for socket_recv and socket_recv_into to handle common operations of both
-// STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) {
-// mp_int_t ret = 0;
-// // int _errno;
-// // mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno);
-// // if (ret == -1) {
-// // mp_raise_OSError(_errno);
-// // }
-// return ret;
-// }
-
-
//| def recv_into(self, buffer: WriteableBuffer, bufsize: int) -> int:
//| """Reads some bytes from the connected remote address, writing
//| into the provided buffer. If bufsize <= len(buffer) is given,
@@ -250,10 +206,10 @@ STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args)
// Bad file number.
mp_raise_OSError(MP_EBADF);
}
- if (!common_hal_socketpool_socket_get_connected(self)) {
- // not connected
- mp_raise_OSError(MP_ENOTCONN);
- }
+ // if (!common_hal_socketpool_socket_get_connected(self)) {
+ // // not connected
+ // mp_raise_OSError(MP_ENOTCONN);
+ // }
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
mp_int_t len = bufinfo.len;
@@ -430,9 +386,9 @@ STATIC const mp_rom_map_elem_t socketpool_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socketpool_socket_close_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socketpool_socket_close_obj) },
- // { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) },
- // { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) },
- // { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socketpool_socket_bind_obj) },
+ { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socketpool_socket_listen_obj) },
+ { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socketpool_socket_accept_obj) },
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socketpool_socket_connect_obj) },
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socketpool_socket_send_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socketpool_socket_sendto_obj) },
diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h
index 54fbe59b2..b5dceb50f 100644
--- a/shared-bindings/socketpool/Socket.h
+++ b/shared-bindings/socketpool/Socket.h
@@ -32,6 +32,11 @@
extern const mp_obj_type_t socketpool_socket_type;
void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t* self, mp_uint_t timeout_ms);
+
+bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t* self, const char* host, size_t hostlen, uint8_t port);
+bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t* self, int backlog);
+socketpool_socket_obj_t * common_hal_socketpool_socket_accept(socketpool_socket_obj_t* self, uint8_t* ip, uint *port);
+
bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const char* host, size_t hostlen, mp_int_t port);
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_recv_into(socketpool_socket_obj_t* self, const uint8_t* buf, mp_uint_t len);
diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c
index 73eeed265..8f4069faa 100644
--- a/shared-bindings/socketpool/SocketPool.c
+++ b/shared-bindings/socketpool/SocketPool.c
@@ -62,14 +62,12 @@ STATIC mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t
//| SOCK_STREAM: int
//| SOCK_DGRAM: int
//| SOCK_RAW: int
-//| IPPROTO_TCP: int
//|
-//| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP) -> socketpool.Socket:
+//| def socket(self, family: int = AF_INET, type: int = SOCK_STREAM) -> socketpool.Socket:
//| """Create a new socket
//|
//| :param ~int family: AF_INET or AF_INET6
-//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW
-//| :param ~int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)"""
+//| :param ~int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW"""
//| ...
//|
diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst
index 1b75e0256..a2fb7987d 100644
--- a/shared-bindings/support_matrix.rst
+++ b/shared-bindings/support_matrix.rst
@@ -1,7 +1,7 @@
.. _module-support-matrix:
-Support Matrix
-===============
+Module Support Matrix - Which Modules Are Available on Which Boards
+===================================================================
The following table lists the available built-in modules for each CircuitPython
capable board.
diff --git a/shared-module/_eve/__init__.c b/shared-module/_eve/__init__.c
index d95c777dc..579729d42 100644
--- a/shared-module/_eve/__init__.c
+++ b/shared-module/_eve/__init__.c
@@ -226,8 +226,9 @@ void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest) {
}
-void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width) {
- C4(eve, ((14 << 24) | ((width & 4095))));
+void common_hal__eve_LineWidth(common_hal__eve_t *eve, mp_float_t width) {
+ int16_t iw = (int)(8 * width);
+ C4(eve, ((14 << 24) | ((iw & 4095))));
}
@@ -246,8 +247,9 @@ void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr) {
}
-void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size) {
- C4(eve, ((13 << 24) | ((size & 8191))));
+void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size) {
+ int16_t is = (int)(8 * size);
+ C4(eve, ((13 << 24) | ((is & 8191))));
}
@@ -301,13 +303,15 @@ void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s) {
}
-void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x) {
- C4(eve, ((43 << 24) | (((x) & 131071))));
+void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, mp_float_t x) {
+ int16_t ix = (int)(16 * x);
+ C4(eve, ((43 << 24) | (ix & 131071)));
}
-void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y) {
- C4(eve, ((44 << 24) | (((y) & 131071))));
+void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, mp_float_t y) {
+ int16_t iy = (int)(16 * y);
+ C4(eve, ((44 << 24) | (iy & 131071)));
}
diff --git a/shared-module/adafruit_bus_device/I2CDevice.c b/shared-module/adafruit_bus_device/I2CDevice.c
index 83abe80d6..792ab7183 100644
--- a/shared-module/adafruit_bus_device/I2CDevice.c
+++ b/shared-module/adafruit_bus_device/I2CDevice.c
@@ -31,48 +31,60 @@
#include "py/runtime.h"
#include "lib/utils/interrupt_char.h"
-void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, busio_i2c_obj_t *i2c, uint8_t device_address) {
+void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t *i2c, uint8_t device_address) {
self->i2c = i2c;
self->device_address = device_address;
}
void common_hal_adafruit_bus_device_i2cdevice_lock(adafruit_bus_device_i2cdevice_obj_t *self) {
- bool success = common_hal_busio_i2c_try_lock(self->i2c);
+ mp_obj_t dest[2];
+ mp_load_method(self->i2c, MP_QSTR_try_lock, dest);
- while (!success) {
+ mp_obj_t success = mp_call_method_n_kw(0, 0, dest);
+
+ while (!mp_obj_is_true(success)) {
RUN_BACKGROUND_TASKS;
if (mp_hal_is_interrupted()) {
break;
}
- success = common_hal_busio_i2c_try_lock(self->i2c);
+ success = mp_call_method_n_kw(0, 0, dest);
}
}
void common_hal_adafruit_bus_device_i2cdevice_unlock(adafruit_bus_device_i2cdevice_obj_t *self) {
- common_hal_busio_i2c_unlock(self->i2c);
-}
-
-uint8_t common_hal_adafruit_bus_device_i2cdevice_readinto(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length) {
- return common_hal_busio_i2c_read(self->i2c, self->device_address, buffer, length);
-}
-
-uint8_t common_hal_adafruit_bus_device_i2cdevice_write(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length, bool transmit_stop_bit) {
- return common_hal_busio_i2c_write(self->i2c, self->device_address, buffer, length, transmit_stop_bit);
+ mp_obj_t dest[2];
+ mp_load_method(self->i2c, MP_QSTR_unlock, dest);
+ mp_call_method_n_kw(0, 0, dest);
}
void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_device_i2cdevice_obj_t *self) {
common_hal_adafruit_bus_device_i2cdevice_lock(self);
- mp_buffer_info_t bufinfo;
- mp_obj_t buffer = mp_obj_new_bytearray_of_zeros(1);
+ mp_buffer_info_t write_bufinfo;
+ mp_obj_t write_buffer = mp_obj_new_bytearray_of_zeros(0);
+ mp_get_buffer_raise(write_buffer, &write_bufinfo, MP_BUFFER_READ);
- mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE);
+ mp_obj_t dest[4];
- uint8_t status = common_hal_adafruit_bus_device_i2cdevice_readinto(self, (uint8_t*)bufinfo.buf, 1);
- if (status != 0) {
+ /* catch exceptions that may be thrown while probing for the device */
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ mp_load_method(self->i2c, MP_QSTR_writeto, dest);
+ dest[2] = mp_obj_new_int_from_ull(self->device_address);
+ dest[3] = write_buffer;
+ mp_call_method_n_kw(2, 0, dest);
+ nlr_pop();
+ } else {
common_hal_adafruit_bus_device_i2cdevice_unlock(self);
- mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address);
+
+ if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t*)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
+ mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address);
+ }
+ else {
+ /* In case we receive an unrelated exception pass it up */
+ nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));
+ }
}
common_hal_adafruit_bus_device_i2cdevice_unlock(self);
diff --git a/shared-module/adafruit_bus_device/I2CDevice.h b/shared-module/adafruit_bus_device/I2CDevice.h
index d06adb9f5..b76bafb2c 100644
--- a/shared-module/adafruit_bus_device/I2CDevice.h
+++ b/shared-module/adafruit_bus_device/I2CDevice.h
@@ -32,7 +32,7 @@
typedef struct {
mp_obj_base_t base;
- busio_i2c_obj_t *i2c;
+ mp_obj_t *i2c;
uint8_t device_address;
} adafruit_bus_device_i2cdevice_obj_t;
diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c
index 39178d46e..103003174 100644
--- a/shared-module/msgpack/__init__.c
+++ b/shared-module/msgpack/__init__.c
@@ -255,11 +255,6 @@ STATIC void pack(mp_obj_t obj, msgpack_stream_t *s, mp_obj_t default_handler) {
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);
@@ -297,7 +292,11 @@ STATIC void pack(mp_obj_t obj, msgpack_stream_t *s, mp_obj_t default_handler) {
} else if (obj == mp_const_true) {
write1(s, 0xc3);
} else {
- if (default_handler != mp_const_none) {
+ mp_buffer_info_t bufinfo;
+ if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_READ)) {
+ // bytes (bin type)
+ pack_bin(s, bufinfo.buf, bufinfo.len);
+ } 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);
@@ -332,7 +331,15 @@ 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);
+ // read in chunks: (some drivers - e.g. UART) limit the
+ // maximum number of bytes that can be read at once
+ // read(s, p, size);
+ while (size > 0) {
+ int n = size > 256 ? 256 : size;
+ read(s, p, n);
+ size -= n;
+ p += n;
+ }
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c
index 39cf40fda..159b54e31 100644
--- a/shared-module/os/__init__.c
+++ b/shared-module/os/__init__.c
@@ -42,6 +42,7 @@
// Version of mp_vfs_lookup_path that takes and returns uPy string objects.
STATIC mp_vfs_mount_t *lookup_path(const char* path, mp_obj_t *path_out) {
const char *p_out;
+ *path_out = mp_const_none;
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out);
if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) {
*path_out = mp_obj_new_str_of_type(&mp_type_str,
@@ -53,6 +54,7 @@ STATIC mp_vfs_mount_t *lookup_path(const char* path, mp_obj_t *path_out) {
// Strip off trailing slashes to please underlying libraries
STATIC mp_vfs_mount_t *lookup_dir_path(const char* path, mp_obj_t *path_out) {
const char *p_out;
+ *path_out = mp_const_none;
mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out);
if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) {
size_t len = strlen(p_out);
diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c
index a09767b62..b8db0d893 100644
--- a/shared-module/rgbmatrix/RGBMatrix.c
+++ b/shared-module/rgbmatrix/RGBMatrix.c
@@ -42,7 +42,7 @@
extern Protomatter_core *_PM_protoPtr;
-void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void *timer) {
+void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void *timer) {
self->width = width;
self->bit_depth = bit_depth;
self->rgb_count = rgb_count;
@@ -53,6 +53,8 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
self->oe_pin = oe_pin;
self->latch_pin = latch_pin;
self->doublebuffer = doublebuffer;
+ self->tile = tile;
+ self->serpentine = serpentine;
self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate();
if (self->timer == NULL) {
@@ -60,7 +62,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
}
self->width = width;
- self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count);
+ self->bufsize = 2 * width * common_hal_rgbmatrix_rgbmatrix_get_height(self);
common_hal_rgbmatrix_rgbmatrix_reconstruct(self, framebuffer);
}
@@ -95,7 +97,8 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
self->rgb_count/6, self->rgb_pins,
self->addr_count, self->addr_pins,
self->clock_pin, self->latch_pin, self->oe_pin,
- self->doublebuffer, self->timer);
+ self->doublebuffer, self->serpentine ? -self->tile : self->tile,
+ self->timer);
if (stat == PROTOMATTER_OK) {
_PM_protoPtr = &self->protomatter;
@@ -209,7 +212,7 @@ int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self) {
}
int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self) {
- int computed_height = (self->rgb_count / 3) << (self->addr_count);
+ int computed_height = (self->rgb_count / 3) * (1 << (self->addr_count)) * self->tile;
return computed_height;
}
diff --git a/shared-module/rgbmatrix/RGBMatrix.h b/shared-module/rgbmatrix/RGBMatrix.h
index 6dbc6fd41..4a0e9235e 100644
--- a/shared-module/rgbmatrix/RGBMatrix.h
+++ b/shared-module/rgbmatrix/RGBMatrix.h
@@ -44,4 +44,6 @@ typedef struct {
bool core_is_initialized;
bool paused;
bool doublebuffer;
+ bool serpentine;
+ int8_t tile;
} rgbmatrix_rgbmatrix_obj_t;
diff --git a/shared-module/sdcardio/SDCard.c b/shared-module/sdcardio/SDCard.c
index 9e861279d..1712f58ee 100644
--- a/shared-module/sdcardio/SDCard.c
+++ b/shared-module/sdcardio/SDCard.c
@@ -375,7 +375,7 @@ int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t
return r;
}
-int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) {
+STATIC int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) {
wait_for_ready(self);
uint8_t cmd[2];
@@ -420,7 +420,7 @@ int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) {
return 0;
}
-int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
+STATIC int writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) {
common_hal_sdcardio_check_for_deinit(self);
uint32_t nblocks = buf->len / 512;
if (nblocks == 1) {
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index 618dc796b..09b30b6ba 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -79,6 +79,8 @@ static void make_sample_code_file(FATFS *fatfs) {
f_open(fatfs, &fs, "/code.py", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fs, buffer, sizeof(buffer) - 1, &char_written);
f_close(&fs);
+ #else
+ make_empty_file(fatfs, "/code.py");
#endif
}
diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c
index 9032e4045..b37b38e08 100644
--- a/supervisor/shared/safe_mode.c
+++ b/supervisor/shared/safe_mode.c
@@ -28,7 +28,9 @@
#include "mphalport.h"
+#if defined(MICROPY_HW_LED_STATUS) || defined(CIRCUITPY_BOOT_BUTTON)
#include "shared-bindings/digitalio/DigitalInOut.h"
+#endif
#include "shared-bindings/microcontroller/Processor.h"
#include "shared-bindings/microcontroller/ResetReason.h"
diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c
index ff08ade18..07c6aee6c 100644
--- a/supervisor/shared/usb/usb.c
+++ b/supervisor/shared/usb/usb.c
@@ -59,12 +59,16 @@ bool usb_enabled(void) {
return tusb_inited();
}
+MP_WEAK void post_usb_init(void) {}
+
void usb_init(void) {
init_usb_hardware();
load_serial_number();
tusb_init();
+ post_usb_init();
+
#if MICROPY_KBD_EXCEPTION
// Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() usb_callback will be invoked when Ctrl+C is received
// This usb_callback always got invoked regardless of mp_interrupt_char value since we only set it once here
diff --git a/supervisor/usb.h b/supervisor/usb.h
index 0dead3e26..ccb35470c 100644
--- a/supervisor/usb.h
+++ b/supervisor/usb.h
@@ -42,6 +42,9 @@ void usb_irq_handler(void);
// TinyUSB.
void init_usb_hardware(void);
+// Temporary hook for code after init. Only used for RP2040.
+void post_usb_init(void);
+
// Shared implementation.
bool usb_enabled(void);
void usb_init(void);
diff --git a/tools/build_board_info.py b/tools/build_board_info.py
index ce9d45fe2..7b556ee5d 100644
--- a/tools/build_board_info.py
+++ b/tools/build_board_info.py
@@ -26,6 +26,7 @@ SUPPORTED_PORTS = [
"litex",
"mimxrt10xx",
"nrf",
+ "raspberrypi",
"stm",
]
@@ -47,6 +48,7 @@ extension_by_port = {
"mimxrt10xx": HEX_UF2,
"litex": DFU,
"esp32s2": BIN_UF2,
+ "raspberrypi": UF2,
}
# Per board overrides
diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py
index 26697b974..89aedf0f4 100644
--- a/tools/build_memory_info.py
+++ b/tools/build_memory_info.py
@@ -9,10 +9,10 @@ import re
import sys
# Handle size constants with K or M suffixes (allowed in .ld but not in Python).
-K_PATTERN = re.compile(r'([0-9]+)K')
+K_PATTERN = re.compile(r'([0-9]+)[kK]')
K_REPLACE = r'(\1*1024)'
-M_PATTERN = re.compile(r'([0-9]+)M')
+M_PATTERN = re.compile(r'([0-9]+)[mM]')
M_REPLACE = r'(\1*1024*1024)'
print()