diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3cd9f6650e..a29a702d87 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,6 +79,10 @@ jobs: - name: Test all run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 working-directory: tests + - name: Print failure info + run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --print-failures + if: failure() + working-directory: tests - name: Native Tests run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --emit native working-directory: tests @@ -228,6 +232,7 @@ jobs: - "bdmicro_vina_d51_pcb7" - "bless_dev_board_multi_sensor" - "blm_badge" + - "bluemicro840" - "capablerobot_usbhub" - "catwan_usbstick" - "circuitbrains_basic_m0" @@ -321,11 +326,13 @@ jobs: - "pewpew10" - "pewpew_m4" - "picoplanet" + - "pimoroni_interstate75" - "pimoroni_keybow2040" - "pimoroni_pga2040" - "pimoroni_picolipo_16mb" - "pimoroni_picolipo_4mb" - "pimoroni_picosystem" + - "pimoroni_plasma2040" - "pimoroni_tiny2040" - "pitaya_go" - "pyb_nano_v2" @@ -341,6 +348,7 @@ jobs: - "qtpy_m0_haxpress" - "raspberry_pi_pico" - "raytac_mdbt50q-db-40" + - "raytac_mdbt50q-rx" - "robohatmm1_m4" - "sam32" - "same54_xplained" @@ -364,6 +372,7 @@ jobs: - "sparkfun_samd21_mini" - "sparkfun_samd51_micromod" - "sparkfun_samd51_thing_plus" + - "sparkfun_stm32f405_micromod" - "sparkfun_thing_plus_rp2040" - "spresense" - "stackrduino_m0_pro" @@ -455,7 +464,7 @@ jobs: - name: Install deps run: | sudo apt-get install -y gettext - pip install requests sh click setuptools awscli + pip install -r requirements-dev.txt wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz sudo tar -C /usr --strip-components=1 -xaf riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz - name: Versions @@ -495,8 +504,10 @@ jobs: - "adafruit_funhouse" - "adafruit_magtag_2.9_grayscale" - "adafruit_metro_esp32s2" + - "ai_thinker_esp_12k_nodemcu" - "artisense_rd00" - "atmegazero_esp32s2" + - "crumpspace_crumps2" - "electroniccats_bastwifi" - "espressif_kaluga_1" - "espressif_kaluga_1.3" @@ -504,10 +515,16 @@ jobs: - "espressif_saola_1_wrover" - "franzininho_wifi_wroom" - "franzininho_wifi_wrover" + - "gravitech_cucumber_m" + - "gravitech_cucumber_ms" + - "gravitech_cucumber_r" + - "gravitech_cucumber_rs" - "lilygo_ttgo_t8_s2_st7789" - "microdev_micro_s2" + - "morpheans_morphesp-240" - "muselab_nanoesp32_s2_wroom" - "muselab_nanoesp32_s2_wrover" + - "odt_pixelwing_esp32_s2" - "targett_module_clip_wroom" - "targett_module_clip_wrover" - "unexpectedmaker_feathers2" diff --git a/.gitmodules b/.gitmodules index 28e429129c..4712d87a8a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -188,3 +188,6 @@ [submodule "frozen/Adafruit_CircuitPython_SimpleIO"] path = frozen/Adafruit_CircuitPython_SimpleIO url = https://github.com/adafruit/adafruit_circuitpython_simpleio +[submodule "lib/quirc"] + path = lib/quirc + url = https://github.com/adafruit/quirc.git diff --git a/README.rst b/README.rst index 9a16c001df..52a48b2b3d 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,7 @@ besides a text editor (we recommend `Mu `_ for beginners.) Starting with CircuitPython 7.0.0, some boards may only be connectable over Bluetooth Low Energy (BLE). Those boards provide serial and file access over BLE instead of USB using open protocols. (Some boards may use both USB and BLE.) BLE access can be done from a variety of apps including -`code.circuitpythonn.org `_. +`code.circuitpython.org `_. CircuitPython features unified Python core APIs and a growing list of 300+ device libraries and drivers that work with it. These libraries also work on single board computers with regular diff --git a/docs/common_hal.md b/docs/common_hal.md index 024c1582c2..b5ce834343 100644 --- a/docs/common_hal.md +++ b/docs/common_hal.md @@ -7,7 +7,7 @@ These instructions also apply to `analogio`, `busio`, `pulseio` and `touchio`. M Common HAL related files are found in these locations: * `shared-bindings` Shared home for the Python <-> C bindings which includes inline RST documentation for the created interfaces. The common hal functions are defined in the .h files of the corresponding C files. -* `shared-modules` Shared home for C code built on the Common HAL and used by all ports. This code only uses `common_hal` methods defined in `shared-bindings`. +* `shared-module` Shared home for C code built on the Common HAL and used by all ports. This code only uses `common_hal` methods defined in `shared-bindings`. * `/common-hal` Port-specific implementation of the Common HAL. Each folder has the substructure of / and they should match 1:1. `__init__.c` is used for module globals that are not classes (similar to `__init__.py`). diff --git a/docs/redirects.txt b/docs/redirects.txt index 6eb7ddc4d8..d8fc46b358 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -152,7 +152,6 @@ shared-bindings/ustack/__init__.rst shared-bindings/ustack/ shared-bindings/vectorio/Circle.rst shared-bindings/vectorio/#vectorio.Circle shared-bindings/vectorio/Polygon.rst shared-bindings/vectorio/#vectorio.Polygon shared-bindings/vectorio/Rectangle.rst shared-bindings/vectorio/#vectorio.Rectangle -shared-bindings/vectorio/VectorShape.rst shared-bindings/vectorio/#vectorio.VectorShape shared-bindings/vectorio/__init__.rst shared-bindings/vectorio/ shared-bindings/watchdog/WatchDogMode.rst shared-bindings/watchdog/#watchdog.WatchDogMode shared-bindings/watchdog/WatchDogTimer.rst shared-bindings/watchdog/#watchdog.WatchDogTimer diff --git a/lib/quirc b/lib/quirc new file mode 160000 index 0000000000..8c6ffa228a --- /dev/null +++ b/lib/quirc @@ -0,0 +1 @@ +Subproject commit 8c6ffa228a4c7643daed7039d3c51d38a43991b8 diff --git a/lib/tinyusb b/lib/tinyusb index 184f1b723f..3a248951e2 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 184f1b723fb811016063deccab9e81640e5c3e7f +Subproject commit 3a248951e2744ba89f5fb96eda85a971001115f0 diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 6ffe5d70a7..31885b94dc 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -167,7 +167,7 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input mp_hal_stdout_tx_strn("\x04", 1); } // check for SystemExit - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { + if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; #if CIRCUITPY_ALARM @@ -183,7 +183,12 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input } if (result != NULL) { result->return_code = ret; + #if CIRCUITPY_ALARM + // Don't set the exception object if we exited for deep sleep. + if (ret != 0 && ret != PYEXEC_DEEP_SLEEP) { + #else if (ret != 0) { + #endif mp_obj_t return_value = (mp_obj_t)nlr.ret_val; result->exception = return_value; result->exception_line = -1; @@ -260,7 +265,7 @@ STATIC mp_uint_t mp_reader_stdin_readbyte(void *data) { mp_hal_stdout_tx_strn("\x04", 1); // indicate end to host if (c == CHAR_CTRL_C) { #if MICROPY_KBD_EXCEPTION - MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; + MP_STATE_VM(mp_kbd_exception).traceback->data = NULL; nlr_raise(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); #else mp_raise_type(&mp_type_KeyboardInterrupt); diff --git a/locale/ID.po b/locale/ID.po index 32e1bd823f..a8bed96e72 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -98,6 +98,10 @@ msgstr "indeks %q harus bilangan bulat, bukan %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "daftar %q harus berupa daftar" @@ -110,14 +114,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -134,10 +130,6 @@ msgstr "%q harus >= 0" msgid "%q must be >= 1" msgstr "%q harus >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -175,6 +167,10 @@ msgstr "%q harus berupa int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -325,6 +321,10 @@ msgstr "'yield from' di dalam fungsi async" msgid "'yield' outside function" msgstr "'yield' diluar fungsi" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x harus menjadi target assignment" @@ -496,6 +496,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1205,11 +1209,6 @@ msgstr "" msgid "Input/output error" msgstr "Kesalahan input/output" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1238,6 +1237,10 @@ msgstr "Otentikasi tidak cukup" msgid "Insufficient encryption" msgstr "Enkripsi tidak cukup" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Kesalahan definisi internal" @@ -1247,7 +1250,7 @@ msgstr "Kesalahan definisi internal" msgid "Internal error #%d" msgstr "Kesalahan internal #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1526,6 +1529,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Harus berupa subclass %q." @@ -1907,21 +1920,6 @@ msgstr "Tambahkan module apapun pada filesystem\n" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Buffer awalan harus ada di heap" @@ -2112,7 +2110,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2567,7 +2564,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "argumen num/types tidak cocok" @@ -3131,6 +3128,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3418,6 +3419,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "format tidak valid" @@ -3455,6 +3460,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3651,10 +3660,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "tidak ada ikatan/bind pada temuan nonlocal" @@ -3950,6 +3955,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4148,7 +4157,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4357,7 +4366,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index e29bfd1ae6..010fa33db2 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -66,6 +66,14 @@ msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "" + #: ports/atmel-samd/common-hal/sdioio/SDCard.c msgid "%q failure: %d" msgstr "" @@ -91,6 +99,10 @@ msgstr "" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -103,14 +115,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -127,10 +131,6 @@ msgstr "" msgid "%q must be >= 1" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -168,6 +168,10 @@ msgstr "" msgid "%q() takes %d positional arguments but %d were given" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -318,6 +322,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -489,6 +497,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1213,6 +1225,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1222,7 +1238,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1506,6 +1522,11 @@ msgstr "" msgid "Missing jmp_pin. Instruction %d jumps on pin" msgstr "" +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -2063,7 +2084,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -3074,6 +3094,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3361,6 +3385,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "" @@ -3398,6 +3426,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3888,6 +3920,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4086,7 +4122,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4295,7 +4331,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index b8ea4b16d5..2050a5c2d4 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -94,6 +94,10 @@ msgstr "Indexy %q musí být celá čísla, nikoli %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "Seznam %q musí být seznam" @@ -106,14 +110,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -130,10 +126,6 @@ msgstr "%q musí být >= 0" msgid "%q must be >= 1" msgstr "%q musí být > = 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -171,6 +163,10 @@ msgstr "%q by měl být int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() vyžaduje %d pozičních argumentů, ale %d jich bylo zadáno" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -321,6 +317,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -492,6 +492,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1188,11 +1192,6 @@ msgstr "" msgid "Input/output error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1221,6 +1220,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1230,7 +1233,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1509,6 +1512,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1880,21 +1893,6 @@ msgstr "" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2081,7 +2079,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2528,7 +2525,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3092,6 +3089,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3379,6 +3380,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "" @@ -3416,6 +3421,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3612,10 +3621,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "" @@ -3910,6 +3915,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4108,7 +4117,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4317,7 +4326,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 7ab3e244a2..84674e9893 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -99,6 +99,10 @@ msgstr "%q Indizes müssen Integer sein, nicht %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q Liste muss eine Liste sein" @@ -111,14 +115,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q muss 0-255 sein" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q muss 1-255 sein" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -135,10 +131,6 @@ msgstr "%q muss >= 0 sein" msgid "%q must be >= 1" msgstr "%q muss >= 1 sein" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "%q muss None oder zwischen 1 und len(report_descriptor)-1 sein" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -177,6 +169,10 @@ msgid "%q() takes %d positional arguments but %d were given" msgstr "" "%q() nimmt %d Argumente ohne Schlüsselwort an, aber es wurden %d angegeben" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -327,6 +323,10 @@ msgstr "'yield from' innerhalb einer async Funktion" msgid "'yield' outside function" msgstr "'yield' außerhalb einer Funktion" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x muss Zuordnungsziel sein" @@ -498,6 +498,10 @@ msgstr "Versuche %d Blöcke zu allokieren" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1205,11 +1209,6 @@ msgstr "Input benötigt zu lange" msgid "Input/output error" msgstr "Eingabe-/Ausgabefehler" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1238,6 +1237,10 @@ msgstr "Unzureichende Authentifizierung" msgid "Insufficient encryption" msgstr "Unzureichende Verschlüsselung" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Interner Definitionsfehler" @@ -1247,7 +1250,7 @@ msgstr "Interner Definitionsfehler" msgid "Internal error #%d" msgstr "Interner Fehler #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "Ungültiger %q" @@ -1527,6 +1530,16 @@ msgstr "Fehlender first_out_pin. Instruktion %d schreibt Pin(s)" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "Fehlender first_set_pin. Instruktion %d setzt Pin(s)" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Muss eine %q Unterklasse sein." @@ -1907,21 +1920,6 @@ msgstr "und alle Module im Dateisystem \n" msgid "Polygon needs at least 3 points" msgstr "Polygone brauchen mindestens 3 Punkte" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Der Präfixbuffer muss sich auf dem Heap befinden" @@ -2110,7 +2108,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2573,7 +2570,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "Anzahl/Typen der Argumente passen nicht" @@ -3149,6 +3146,10 @@ msgstr "f-string: einzelne '}' nicht erlaubt" msgid "file must be a file opened in byte mode" msgstr "Die Datei muss eine im Byte-Modus geöffnete Datei sein" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "Das Dateisystem muss eine Mount-Methode bereitstellen" @@ -3438,6 +3439,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "ungültiges Format" @@ -3475,6 +3480,10 @@ msgstr "ungültige Syntax für integer mit Basis %d" msgid "invalid syntax for number" msgstr "ungültige Syntax für number" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 muss eine Klasse sein" @@ -3677,10 +3686,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "Keine aktive Ausnahme zu verusachen (raise)" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "kein verfügbares Netzwerkadapter (NIC)" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "Kein Binding für nonlocal gefunden" @@ -3979,6 +3984,10 @@ msgstr "pow () mit 3 Argumenten erfordert Integer" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4179,7 +4188,7 @@ msgstr "stop muss 1 oder 2 sein" msgid "stop not reachable from start" msgstr "stop ist von start aus nicht erreichbar" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation ist nicht unterstützt" @@ -4393,7 +4402,7 @@ msgid "unreadable attribute" msgstr "nicht lesbares Attribut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Nicht unterstützter %q-Typ" @@ -4514,6 +4523,18 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "%q must be 0-255" +#~ msgstr "%q muss 0-255 sein" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q muss 1-255 sein" + +#~ msgid "%q must be None or between 1 and len(report_descriptor)-1" +#~ msgstr "%q muss None oder zwischen 1 und len(report_descriptor)-1 sein" + +#~ msgid "no available NIC" +#~ msgstr "kein verfügbares Netzwerkadapter (NIC)" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "Instruktion %d springt auf Pin" diff --git a/locale/el.po b/locale/el.po index ecc4baef85..7ff51ae54d 100644 --- a/locale/el.po +++ b/locale/el.po @@ -91,6 +91,10 @@ msgstr "" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -103,14 +107,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -127,10 +123,6 @@ msgstr "" msgid "%q must be >= 1" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -168,6 +160,10 @@ msgstr "" msgid "%q() takes %d positional arguments but %d were given" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -318,6 +314,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -489,6 +489,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1185,11 +1189,6 @@ msgstr "" msgid "Input/output error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1218,6 +1217,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1227,7 +1230,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1506,6 +1509,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1877,21 +1890,6 @@ msgstr "" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2078,7 +2076,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2525,7 +2522,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3089,6 +3086,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3376,6 +3377,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "" @@ -3413,6 +3418,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3609,10 +3618,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "" @@ -3907,6 +3912,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4105,7 +4114,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4314,7 +4323,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index 0ca8c4518a..cbc6072e11 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -100,6 +100,10 @@ msgstr "" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q list must be a list" @@ -112,14 +116,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -136,10 +132,6 @@ msgstr "%q must be >= 0" msgid "%q must be >= 1" msgstr "%q must be >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -177,6 +169,10 @@ msgstr "%q should be an int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() takes %d positional arguments but %d were given" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -327,6 +323,10 @@ msgstr "'yield from' inside async function" msgid "'yield' outside function" msgstr "'yield' outside function" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x must be assignment target" @@ -498,6 +498,10 @@ msgstr "Attempt to allocate %d blocks" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1200,11 +1204,6 @@ msgstr "Input taking too long" msgid "Input/output error" msgstr "Input/output error" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1233,6 +1232,10 @@ msgstr "Insufficient authentication" msgid "Insufficient encryption" msgstr "Insufficient encryption" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Internal define error" @@ -1242,7 +1245,7 @@ msgstr "Internal define error" msgid "Internal error #%d" msgstr "Internal error #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "Invalid %q" @@ -1521,6 +1524,16 @@ msgstr "Missing first_out_pin. Instruction %d writes pin(s)" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "Missing first_set_pin. Instruction %d sets pin(s)" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Must be a %q subclass." @@ -1901,25 +1914,6 @@ msgstr "Plus any modules on the filesystem\n" msgid "Polygon needs at least 3 points" msgstr "Polygon needs at least 3 points" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Prefix buffer must be on the heap" @@ -2106,7 +2100,6 @@ msgid "Size not supported" msgstr "Size not supported" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2560,7 +2553,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "argument num/types mismatch" @@ -3127,6 +3120,10 @@ msgstr "f-string: single '}' is not allowed" msgid "file must be a file opened in byte mode" msgstr "file must be a file opened in byte mode" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "filesystem must provide mount method" @@ -3414,6 +3411,10 @@ msgstr "invalid element size %d for bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "invalid element_size %d, must be, 1, 2, or 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "invalid format" @@ -3452,6 +3453,10 @@ msgstr "invalid syntax for integer with base %d" msgid "invalid syntax for number" msgstr "invalid syntax for number" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 must be a class" @@ -3648,10 +3653,6 @@ msgstr "no SD card" msgid "no active exception to reraise" msgstr "no active exception to reraise" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "no available NIC" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "no binding for nonlocal found" @@ -3946,6 +3947,10 @@ msgstr "pow() with 3 arguments requires integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4146,7 +4151,7 @@ msgstr "stop must be 1 or 2" msgid "stop not reachable from start" msgstr "stop not reachable from start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation not supported" @@ -4355,7 +4360,7 @@ msgid "unreadable attribute" msgstr "unreadable attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "unsupported %q type" @@ -4476,6 +4481,23 @@ msgstr "zi must be of float type" msgid "zi must be of shape (n_section, 2)" msgstr "zi must be of shape (n_section, 2)" +#~ msgid "no available NIC" +#~ msgstr "no available NIC" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "Instruction %d jumps on pin" diff --git a/locale/es.po b/locale/es.po index 8305b1dff5..8af1070316 100644 --- a/locale/es.po +++ b/locale/es.po @@ -102,6 +102,10 @@ msgstr "%q indices deben ser enteros, no %s" msgid "%q length must be %q" msgstr "el tamaño de %q debe ser %q" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q lista debe ser una lista" @@ -114,14 +118,6 @@ msgstr "%q debe ser <= %d" msgid "%q must be %d-%d" msgstr "%q debe ser %d-%d" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q debe ser de 0-255" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q debe estar entre 1-255" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "%q debe ser >= %d" @@ -138,10 +134,6 @@ msgstr "%q debe ser >= 0" msgid "%q must be >= 1" msgstr "%q debe ser >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "%q debe ser None o entre 1 y len(report_descriptor)-1" - #: py/argcheck.c msgid "%q must be a string" msgstr "%q debe ser una cadena" @@ -179,6 +171,10 @@ msgstr "%q debe ser un int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -329,6 +325,10 @@ msgstr "'yield from' dentro de una función asincrónica" msgid "'yield' outside function" msgstr "'yield' fuera de una función" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x debe ser objetivo de la tarea" @@ -502,6 +502,10 @@ msgstr "Tratando de localizar %d bloques" msgid "Attempted heap allocation when VM not running." msgstr "Asignación del montículo mientras la VM no esta ejecutándose." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN no se usa con contraseña" @@ -1218,11 +1222,6 @@ msgstr "La entrada está durando mucho tiempo" msgid "Input/output error" msgstr "error Input/output" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1251,6 +1250,10 @@ msgstr "Autenticación insuficiente" msgid "Insufficient encryption" msgstr "Cifrado insuficiente" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Error interno de definición" @@ -1260,7 +1263,7 @@ msgstr "Error interno de definición" msgid "Internal error #%d" msgstr "Error interno #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "%q inválido" @@ -1543,6 +1546,16 @@ msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" "first_set_pin no encontrado. La instrucción %d configura el/los pin(es)" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Debe de ser una subclase de %q." @@ -1925,25 +1938,6 @@ msgstr "Además de cualquier módulo en el sistema de archivos\n" msgid "Polygon needs at least 3 points" msgstr "El polígono necesita al menos 3 puntos" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"Port no acepta un carrier de PWM. Pase en cambio un pin, una frecuencia o un " -"ciclo de actividad" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Port no acepta los pines o la frecuencia. Construya y pase en su lugar un " -"Carrier de PWMOut" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "El prefijo del buffer debe estar en el heap" @@ -2134,7 +2128,6 @@ msgid "Size not supported" msgstr "Sin capacidades para el tamaño" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "Memoria de sueño no disponible" @@ -2604,7 +2597,7 @@ msgid "argument name reused" msgstr "nombre de argumento reutilizado" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "argumento número/tipos no coinciden" @@ -3175,6 +3168,10 @@ msgstr "cadena-f: solo '}' no está permitido" msgid "file must be a file opened in byte mode" msgstr "el archivo deberia ser una archivo abierto en modo byte" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "sistema de archivos debe proporcionar método de montaje" @@ -3462,6 +3459,10 @@ msgstr "el tamaño del elemento no es valido%d por bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "el element_size %d,no es valido, debe ser 1,2 ó 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "formato inválido" @@ -3499,6 +3500,10 @@ msgstr "sintaxis inválida para entero con base %d" msgid "invalid syntax for number" msgstr "sintaxis inválida para número" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 debe ser una clase" @@ -3699,10 +3704,6 @@ msgstr "no hay tarjeta SD" msgid "no active exception to reraise" msgstr "exception no activa para reraise" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "NIC no disponible" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "no se ha encontrado ningún enlace para nonlocal" @@ -4000,6 +4001,10 @@ msgstr "pow() con 3 argumentos requiere enteros" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4200,7 +4205,7 @@ msgstr "stop debe ser 1 ó 2" msgid "stop not reachable from start" msgstr "stop no se puede alcanzar del principio" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operación stream no soportada" @@ -4410,7 +4415,7 @@ msgid "unreadable attribute" msgstr "atributo no legible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo de %q no soportado" @@ -4531,6 +4536,32 @@ 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 "%q must be 0-255" +#~ msgstr "%q debe ser de 0-255" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q debe estar entre 1-255" + +#~ msgid "%q must be None or between 1 and len(report_descriptor)-1" +#~ msgstr "%q debe ser None o entre 1 y len(report_descriptor)-1" + +#~ msgid "no available NIC" +#~ msgstr "NIC no disponible" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Port no acepta un carrier de PWM. Pase en cambio un pin, una frecuencia o " +#~ "un ciclo de actividad" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Port no acepta los pines o la frecuencia. Construya y pase en su lugar un " +#~ "Carrier de PWMOut" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "La instruction %d salta en pin" diff --git a/locale/fil.po b/locale/fil.po index e5057ab83e..3e6c89386d 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -90,6 +90,10 @@ msgstr "%q indeks ay dapat integers, hindi %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -102,14 +106,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -127,10 +123,6 @@ msgstr "" msgid "%q must be >= 1" msgstr "aarehas na haba dapat ang buffer slices" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -170,6 +162,10 @@ msgid "%q() takes %d positional arguments but %d were given" msgstr "" "Ang %q() ay kumukuha ng %d positional arguments pero %d lang ang binigay" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -320,6 +316,10 @@ msgstr "" msgid "'yield' outside function" msgstr "'yield' sa labas ng function" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x ay dapat na assignment target" @@ -492,6 +492,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1200,11 +1204,6 @@ msgstr "" msgid "Input/output error" msgstr "May mali sa Input/Output" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1233,6 +1232,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1242,7 +1245,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1521,6 +1524,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1896,21 +1909,6 @@ msgstr "Kasama ang kung ano pang modules na sa filesystem\n" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2098,7 +2096,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2553,7 +2550,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "hindi tugma ang argument num/types" @@ -3129,6 +3126,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "file ay dapat buksan sa byte mode" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "ang filesystem dapat mag bigay ng mount method" @@ -3417,6 +3418,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "hindi wastong pag-format" @@ -3454,6 +3459,10 @@ msgstr "maling sintaks sa integer na may base %d" msgid "invalid syntax for number" msgstr "maling sintaks sa number" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 ay dapat na class" @@ -3654,10 +3663,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "walang aktibong exception para i-reraise" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "walang magagamit na NIC" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "no binding para sa nonlocal, nahanap" @@ -3954,6 +3959,10 @@ msgstr "pow() na may 3 argumento kailangan ng integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4155,7 +4164,7 @@ msgstr "stop dapat 1 o 2" msgid "stop not reachable from start" msgstr "stop hindi maabot sa simula" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation hindi sinusuportahan" @@ -4365,7 +4374,7 @@ msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Hindi supportadong tipo ng %q" @@ -4488,6 +4497,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "no available NIC" +#~ msgstr "walang magagamit na NIC" + #~ msgid "USB Busy" #~ msgstr "Busy ang USB" diff --git a/locale/fr.po b/locale/fr.po index bf97797f5f..b9b6c7b108 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -102,6 +102,10 @@ msgstr "les indices %q doivent être des entiers, pas %s" msgid "%q length must be %q" msgstr "La longueur de %q doit être de %q" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "La liste %q doit être une liste" @@ -114,14 +118,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q doit être compris entre 0 et 255" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q doit être compris entre 1 et 255" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -138,10 +134,6 @@ msgstr "%q doit être >= 0" msgid "%q must be >= 1" msgstr "%q doit être >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "%q doit être une chaîne de caractères" @@ -179,6 +171,10 @@ msgstr "%q doit être un chiffre entier (int)" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prend %d paramètres positionnels mais %d ont été donnés" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -329,6 +325,10 @@ msgstr "'yield from' dans une fonction async" msgid "'yield' outside function" msgstr "'yield' dehors d'une fonction" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x doit être la cible de l'assignement" @@ -504,6 +504,10 @@ msgstr "" "Tentative d'allocation à la pile quand la Machine Virtuelle n'est pas en " "exécution." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN n'est pas utilisé avec un mot de passe" @@ -1224,11 +1228,6 @@ msgstr "L'entrée prend trop de temps" msgid "Input/output error" msgstr "Erreur d'entrée/sortie" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1261,6 +1260,10 @@ msgstr "Authentification insuffisante" msgid "Insufficient encryption" msgstr "Chiffrement insuffisant" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Erreur de définition interne" @@ -1270,7 +1273,7 @@ msgstr "Erreur de définition interne" msgid "Internal error #%d" msgstr "Erreur interne #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "%q invalide" @@ -1551,6 +1554,16 @@ msgstr "first_out_pin manquant. Instruction %d écrit un/des broche(s)" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "first_set_pin manquant. L'instruction %d règle la/les broche(s)" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Doit être une sous-classe de %q." @@ -1935,25 +1948,6 @@ msgstr "Ainsi que tout autres modules présents sur le système de fichiers\n" msgid "Polygon needs at least 3 points" msgstr "Polygon a besoin d’au moins 3 points" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"Ce port n'accepte pas de PWM carrier. Précisez plutôt les valeurs pin, " -"frequency et duty_cycle" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Ce port n'accepte pas de broches ou de fréquence. Construisez plutôt en " -"passant un PWMOut Carrier" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Le tampon de préfixe doit être sur la pile" @@ -2143,7 +2137,6 @@ msgid "Size not supported" msgstr "Taille n'est pas supportée" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2606,7 +2599,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "Nombre/types de paramètres ne correspondent pas" @@ -3183,6 +3176,10 @@ msgstr "f-string : single '}' n'est pas autorisé" msgid "file must be a file opened in byte mode" msgstr "le fichier doit être un fichier ouvert en mode 'byte'" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "le system de fichier doit fournir une méthode 'mount'" @@ -3471,6 +3468,10 @@ msgstr "taille d'élément %d est invalide pour bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "element_size %d est invalide, doit être 1, 2 ou 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "format invalide" @@ -3508,6 +3509,10 @@ msgstr "syntaxe invalide pour un entier de base %d" msgid "invalid syntax for number" msgstr "syntaxe invalide pour un nombre" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "l'argument 1 de issubclass() doit être une classe" @@ -3708,10 +3713,6 @@ msgstr "pas de carte SD" msgid "no active exception to reraise" msgstr "aucune exception active à relever" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "adapteur réseau non disponible" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "pas de lien trouvé pour nonlocal" @@ -4011,6 +4012,10 @@ msgstr "pow() avec 3 arguments nécessite des entiers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4211,7 +4216,7 @@ msgstr "stop doit être 1 ou 2" msgid "stop not reachable from start" msgstr "stop n'est pas accessible au démarrage" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "opération de flux non supportée" @@ -4421,7 +4426,7 @@ msgid "unreadable attribute" msgstr "attribut illisible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "type %q non pris on charge" @@ -4542,6 +4547,29 @@ 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 "%q must be 0-255" +#~ msgstr "%q doit être compris entre 0 et 255" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q doit être compris entre 1 et 255" + +#~ msgid "no available NIC" +#~ msgstr "adapteur réseau non disponible" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Ce port n'accepte pas de PWM carrier. Précisez plutôt les valeurs pin, " +#~ "frequency et duty_cycle" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Ce port n'accepte pas de broches ou de fréquence. Construisez plutôt en " +#~ "passant un PWMOut Carrier" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "Instruction %d saute sur la broche" diff --git a/locale/hi.po b/locale/hi.po index 99fd695dda..664e2c37ea 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -91,6 +91,10 @@ msgstr "" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -103,14 +107,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -127,10 +123,6 @@ msgstr "" msgid "%q must be >= 1" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -168,6 +160,10 @@ msgstr "" msgid "%q() takes %d positional arguments but %d were given" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -318,6 +314,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -489,6 +489,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1185,11 +1189,6 @@ msgstr "" msgid "Input/output error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1218,6 +1217,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1227,7 +1230,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1506,6 +1509,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1877,21 +1890,6 @@ msgstr "" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2078,7 +2076,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2525,7 +2522,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3089,6 +3086,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3376,6 +3377,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "" @@ -3413,6 +3418,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3609,10 +3618,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "" @@ -3907,6 +3912,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4105,7 +4114,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4314,7 +4323,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 412d3e03fe..13082dc048 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -100,6 +100,10 @@ msgstr "gli indici %q devono essere interi, non %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "lista %q deve essere una lista" @@ -112,14 +116,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -137,10 +133,6 @@ msgstr "%q deve essere >= 0" msgid "%q must be >= 1" msgstr "slice del buffer devono essere della stessa lunghezza" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -178,6 +170,10 @@ msgstr "%q dovrebbe essere un int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() prende %d argomenti posizionali ma ne sono stati forniti %d" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -329,6 +325,10 @@ msgstr "'yield from' è nella funzione sincronizzazione" msgid "'yield' outside function" msgstr "'yield' al di fuori della funzione" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x deve essere il bersaglio del assegnamento" @@ -501,6 +501,10 @@ msgstr "Provo ad allocare %d blocchi" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1209,11 +1213,6 @@ msgstr "" msgid "Input/output error" msgstr "Errore input/output" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1242,6 +1241,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1251,7 +1254,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1534,6 +1537,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1915,21 +1928,6 @@ msgstr "Imposssibile rimontare il filesystem" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2119,7 +2117,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2568,7 +2565,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "discrepanza di numero/tipo di argomenti" @@ -3142,6 +3139,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "il filesystem deve fornire un metodo di mount" @@ -3430,6 +3431,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "formato non valido" @@ -3467,6 +3472,10 @@ msgstr "sintassi invalida per l'intero con base %d" msgid "invalid syntax for number" msgstr "sintassi invalida per il numero" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "il primo argomento di issubclass() deve essere una classe" @@ -3668,11 +3677,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "nessuna eccezione attiva da rilanciare" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -#, fuzzy -msgid "no available NIC" -msgstr "busio.UART non ancora implementato" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "nessun binding per nonlocal trovato" @@ -3973,6 +3977,10 @@ msgstr "pow() con 3 argomenti richiede interi" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4174,7 +4182,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "stop non raggiungibile dall'inizio" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operazione di stream non supportata" @@ -4384,7 +4392,7 @@ msgid "unreadable attribute" msgstr "attributo non leggibile" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo di %q non supportato" @@ -4507,6 +4515,10 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#, fuzzy +#~ msgid "no available NIC" +#~ msgstr "busio.UART non ancora implementato" + #~ msgid "Buffer too large and unable to allocate" #~ msgstr "Buffer troppo grande ed impossibile allocare" diff --git a/locale/ja.po b/locale/ja.po index a1c850be2f..680adcf705 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -96,6 +96,10 @@ msgstr "" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q リストはリストでなければなりません" @@ -108,14 +112,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -132,10 +128,6 @@ msgstr "%qは0以上でなければなりません" msgid "%q must be >= 1" msgstr "%qは1以上でなければなりません" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -173,6 +165,10 @@ msgstr "%qはint型でなければなりません" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() は %d 個の位置引数を取りますが、%d 個与えられました" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -323,6 +319,10 @@ msgstr "" msgid "'yield' outside function" msgstr "関数外でのyield" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*xは代入先でなければなりません" @@ -494,6 +494,10 @@ msgstr "%d個のブロックの確保を試みました" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1196,11 +1200,6 @@ msgstr "" msgid "Input/output error" msgstr "入力/出力エラー" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1229,6 +1228,10 @@ msgstr "認証が不十分" msgid "Insufficient encryption" msgstr "暗号化が不十分" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "内部定義エラー" @@ -1238,7 +1241,7 @@ msgstr "内部定義エラー" msgid "Internal error #%d" msgstr "内部エラー #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "不正な %q" @@ -1517,6 +1520,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "%q のサブクラスでなければなりません" @@ -1891,21 +1904,6 @@ msgstr "" msgid "Polygon needs at least 3 points" msgstr "ポリゴンには少なくとも3つの点が必要" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Prefixバッファはヒープ上になければなりません" @@ -2092,7 +2090,6 @@ msgid "Size not supported" msgstr "サイズは対応していません" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2540,7 +2537,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3108,6 +3105,10 @@ msgstr "f-string: 1つだけの'}'は許されません" msgid "file must be a file opened in byte mode" msgstr "fileはバイトモードで開かれたファイルでなければなりません" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "filesystemはmountメソッドを提供しなければなりません" @@ -3396,6 +3397,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "" @@ -3433,6 +3438,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "数字として不正な構文" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass()の第1引数はクラスでなければなりません" @@ -3629,10 +3638,6 @@ msgstr "SDカードがありません" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "利用可能なNICがありません" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "nonlocalの対象が見つかりません" @@ -3929,6 +3934,10 @@ msgstr "pow()の第3引数には整数が必要" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4128,7 +4137,7 @@ msgstr "stopは1または2のいずれか" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "ストリーム操作は非対応" @@ -4337,7 +4346,7 @@ msgid "unreadable attribute" msgstr "読み込み不可能な属性" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "非対応の型 %q" @@ -4458,6 +4467,9 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "no available NIC" +#~ msgstr "利用可能なNICがありません" + #~ msgid "Buffer too large and unable to allocate" #~ msgstr "バッファが大きすぎて確保できません" diff --git a/locale/ko.po b/locale/ko.po index 556574d372..87e4c0583f 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -92,6 +92,10 @@ msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -104,14 +108,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -128,10 +124,6 @@ msgstr "" msgid "%q must be >= 1" msgstr "%q 는 >=1이어야합니다" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -169,6 +161,10 @@ msgstr "%q 는 정수(int) 여야합니다" msgid "%q() takes %d positional arguments but %d were given" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -319,6 +315,10 @@ msgstr "" msgid "'yield' outside function" msgstr "'yield' 는 함수 외부에 존재합니다" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -490,6 +490,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1188,11 +1192,6 @@ msgstr "" msgid "Input/output error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1221,6 +1220,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1230,7 +1233,7 @@ msgstr "" msgid "Internal error #%d" msgstr "" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "" @@ -1509,6 +1512,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1880,21 +1893,6 @@ msgstr "" msgid "Polygon needs at least 3 points" msgstr "" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2081,7 +2079,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2529,7 +2526,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3093,6 +3090,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "" @@ -3380,6 +3381,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "형식가 유효하지 않습니다" @@ -3417,6 +3422,10 @@ msgstr "구문(syntax)가 정수가 유효하지 않습니다" msgid "invalid syntax for number" msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3613,10 +3622,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "" @@ -3911,6 +3916,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4109,7 +4118,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" @@ -4318,7 +4327,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 73d6276635..735861fa82 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -94,6 +94,10 @@ msgstr "%q indexen moeten integers zijn, niet %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q lijst moet een lijst zijn" @@ -106,14 +110,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -130,10 +126,6 @@ msgstr "%q moet >= 0 zijn" msgid "%q must be >= 1" msgstr "%q moet >= 1 zijn" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -171,6 +163,10 @@ msgstr "%q moet een int zijn" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() verwacht %d positionele argumenten maar kreeg %d" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -321,6 +317,10 @@ msgstr "'yield from' binnen asynchrone functie" msgid "'yield' outside function" msgstr "'yield' buiten de functie" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x moet een assignment target zijn" @@ -492,6 +492,10 @@ msgstr "Poging om %d blokken toe te wijzen" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1197,11 +1201,6 @@ msgstr "Invoer duurt te lang" msgid "Input/output error" msgstr "Input/Output fout" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1230,6 +1229,10 @@ msgstr "Onvoldoende authenticatie" msgid "Insufficient encryption" msgstr "Onvoldoende encryptie" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Interne define fout" @@ -1239,7 +1242,7 @@ msgstr "Interne define fout" msgid "Internal error #%d" msgstr "Interne fout #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "Ongeldige %q" @@ -1518,6 +1521,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "%q moet een subklasse zijn." @@ -1901,25 +1914,6 @@ msgstr "En iedere module in het bestandssysteem\n" msgid "Polygon needs at least 3 points" msgstr "Polygon heeft op zijn minst 3 punten nodig" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"Poort ondersteund geen PWM drager. Geef een pin, frequentie en inschakeltijd " -"op" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Poort accepteert geen pin of frequentie. Stel een PWMOut Carrier samen en " -"geef die op" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Prefix buffer moet op de heap zijn" @@ -2108,7 +2102,6 @@ msgid "Size not supported" msgstr "Afmeting niet ondersteund" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2566,7 +2559,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "argument num/typen komen niet overeen" @@ -3134,6 +3127,10 @@ msgstr "f-string: enkele '}' is niet toegestaan" msgid "file must be a file opened in byte mode" msgstr "bestand moet een bestand zijn geopend in byte modus" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "bestandssysteem moet een mount methode bieden" @@ -3422,6 +3419,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "ongeldig formaat" @@ -3459,6 +3460,10 @@ msgstr "ongeldige syntax voor integer met grondtal %d" msgid "invalid syntax for number" msgstr "ongeldige syntax voor nummer" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() argument 1 moet een klasse zijn" @@ -3658,10 +3663,6 @@ msgstr "geen SD kaart" msgid "no active exception to reraise" msgstr "geen actieve uitzondering om opnieuw op te werpen (raise)" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "geen netwerkadapter (NIC) beschikbaar" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "geen binding voor nonlocal gevonden" @@ -3957,6 +3958,10 @@ msgstr "pow() met 3 argumenten vereist integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4157,7 +4162,7 @@ msgstr "stop moet 1 of 2 zijn" msgid "stop not reachable from start" msgstr "stop is niet bereikbaar vanaf start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operatie niet ondersteund" @@ -4366,7 +4371,7 @@ msgid "unreadable attribute" msgstr "onleesbaar attribuut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "niet ondersteund %q type" @@ -4487,6 +4492,23 @@ 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 "no available NIC" +#~ msgstr "geen netwerkadapter (NIC) beschikbaar" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Poort ondersteund geen PWM drager. Geef een pin, frequentie en " +#~ "inschakeltijd op" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Poort accepteert geen pin of frequentie. Stel een PWMOut Carrier samen en " +#~ "geef die op" + #~ msgid "Buffer too large and unable to allocate" #~ msgstr "Buffer is te groot en niet in staat te alloceren" diff --git a/locale/pl.po b/locale/pl.po index 262f8c5a89..f7c46fa7e3 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -96,6 +96,10 @@ msgstr "%q indeks musi być liczbą całkowitą, a nie %s" msgid "%q length must be %q" msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "" @@ -108,14 +112,6 @@ msgstr "" msgid "%q must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "" @@ -132,10 +128,6 @@ msgstr "%q musi być >= 0" msgid "%q must be >= 1" msgstr "%q musi być >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "" - #: py/argcheck.c msgid "%q must be a string" msgstr "" @@ -173,6 +165,10 @@ msgstr "%q powinno być typu int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() bierze %d argumentów pozycyjnych, lecz podano %d" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -323,6 +319,10 @@ msgstr "'yield from' wewnątrz funkcji asynchronicznej" msgid "'yield' outside function" msgstr "'yield' poza funkcją" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x musi być obiektem przypisania" @@ -494,6 +494,10 @@ msgstr "Próba przydzielenia %d bloków" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1196,11 +1200,6 @@ msgstr "" msgid "Input/output error" msgstr "Błąd I/O" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1229,6 +1228,10 @@ msgstr "Niewystarczające uwierzytelnienie" msgid "Insufficient encryption" msgstr "Niewystarczające szyfrowanie" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" @@ -1238,7 +1241,7 @@ msgstr "" msgid "Internal error #%d" msgstr "Błąd wewnętrzny #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "Nieprawidłowe %q" @@ -1517,6 +1520,16 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1888,21 +1901,6 @@ msgstr "Oraz moduły w systemie plików\n" msgid "Polygon needs at least 3 points" msgstr "Wielokąt musi mieć co najmniej 3 punkty" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2089,7 +2087,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2542,7 +2539,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "zła liczba lub typ argumentów" @@ -3107,6 +3104,10 @@ msgstr "" msgid "file must be a file opened in byte mode" msgstr "file musi być otwarte w trybie bajtowym" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "system plików musi mieć metodę mount" @@ -3394,6 +3395,10 @@ msgstr "" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "zły format" @@ -3431,6 +3436,10 @@ msgstr "zła składnia dla liczby całkowitej w bazie %d" msgid "invalid syntax for number" msgstr "zła składnia dla liczby" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "argument 1 dla issubclass() musi być klasą" @@ -3627,10 +3636,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "brak wyjątku do ponownego rzucenia" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "brak wolnego NIC" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "brak wiązania dla zmiennej nielokalnej" @@ -3926,6 +3931,10 @@ msgstr "trzyargumentowe pow() wymaga liczb całkowitych" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4125,7 +4134,7 @@ msgstr "stop musi być 1 lub 2" msgid "stop not reachable from start" msgstr "stop nie jest osiągalne ze start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operacja na strumieniu nieobsługiwana" @@ -4334,7 +4343,7 @@ msgid "unreadable attribute" msgstr "nieczytelny atrybut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "zły typ %q" @@ -4455,6 +4464,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "no available NIC" +#~ msgstr "brak wolnego NIC" + #~ msgid "Buffer too large and unable to allocate" #~ msgstr "Bufor jest zbyt duży i nie można go przydzielić" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index dd2ccb5833..33bd704e25 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-07-24 15:35+0000\n" +"PO-Revision-Date: 2021-08-13 12:33+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.7.2-dev\n" +"X-Generator: Weblate 4.8-dev\n" #: main.c msgid "" @@ -100,6 +100,10 @@ msgstr "Os índices %q devem ser inteiros, e não %s" msgid "%q length must be %q" msgstr "o comprimento %q deve ser %q" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "A lista %q deve ser uma lista" @@ -112,14 +116,6 @@ msgstr "o %q deve ser <= %d" msgid "%q must be %d-%d" msgstr "o %q deve ser %d-%d" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q deve ser entre 0-255" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q deve ser 1-255" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "o %q deve ser >= %d" @@ -136,10 +132,6 @@ msgstr "%q deve ser >= 0" msgid "%q must be >= 1" msgstr "%q deve ser >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "%q deve ser None ou entre 1 e len(report_descriptor)-1" - #: py/argcheck.c msgid "%q must be a string" msgstr "%q deve ser uma string" @@ -177,6 +169,10 @@ msgstr "%q deve ser um int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() recebe %d argumentos posicionais, porém %d foram informados" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -331,6 +327,10 @@ msgstr "'yield a partir' de dentro da função async" msgid "'yield' outside function" msgstr "função externa 'yield'" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "(x,y) é obrigatório o uso de números inteiros" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x deve ser o destino da atribuição" @@ -503,6 +503,10 @@ msgid "Attempted heap allocation when VM not running." msgstr "" "Tentativa de alocação das pilhas quando o VM não estiver em funcionamento." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "A conversão de áudio ainda não foi implementada" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "O AuthMode.OPEN não é usado com senha" @@ -1219,11 +1223,6 @@ msgstr "A entrada está demorando demais" msgid "Input/output error" msgstr "Erro de entrada/saída" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "Falta o jmp_pin. A instrução %d salta no pino" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1252,6 +1251,10 @@ msgstr "Autenticação insuficiente" msgid "Insufficient encryption" msgstr "Criptografia insuficiente" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "O buffer interno de áudio é muito pequeno" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Erro interno de definição" @@ -1261,7 +1264,7 @@ msgstr "Erro interno de definição" msgid "Internal error #%d" msgstr "Erro interno #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "%q Inválido" @@ -1540,6 +1543,16 @@ msgstr "Faltando first_out_pin. A instrução %d escreve nos pinos(s)" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "Faltando first_set_pin. A instrução %d define os pinos(s)" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "Falta o jmp_pin. A instrução %d salta no pino" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Deve ser uma subclasse %q." @@ -1925,25 +1938,6 @@ msgstr "Além de quaisquer módulos no sistema de arquivos\n" msgid "Polygon needs at least 3 points" msgstr "O Polígono precisa de pelo menos 3 pontos" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"A porta não aceita portadora PWM. Em vez disso informe um pino, frequência e " -"o ciclo de trabalho" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"A porta não aceita pinos ou frequência. Em vez disso, construa e passe um " -"PWMOut Carrier" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "" @@ -2136,7 +2130,6 @@ msgid "Size not supported" msgstr "O tamanho não é suportado" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "Sleep memory não está disponível" @@ -2609,7 +2602,7 @@ msgid "argument name reused" msgstr "nome do argumento reutilizado" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "o argumento num/tipos não combinam" @@ -3182,6 +3175,10 @@ msgstr "f-string: um único '}' não é permitido" msgid "file must be a file opened in byte mode" msgstr "o arquivo deve ser um arquivo aberto no modo byte" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "a gravação de arquivos não está disponível" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "sistema de arquivos deve fornecer método de montagem" @@ -3470,6 +3467,10 @@ msgstr "tamanho do elemento %d é inválido para bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "element_size %d é inválido, deve ser, 1, 2, ou 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "exceção inválida" + #: extmod/modframebuf.c msgid "invalid format" msgstr "formato inválido" @@ -3507,6 +3508,10 @@ msgstr "sintaxe inválida para o número inteiro com base %d" msgid "invalid syntax for number" msgstr "sintaxe inválida para o número" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "rastreamento inválido" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 deve ser uma classe" @@ -3708,10 +3713,6 @@ msgstr "nenhum cartão SD" msgid "no active exception to reraise" msgstr "nenhuma exceção ativa para reraise" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "não há uma Placa de Rede disponível" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "nenhuma ligação para nonlocal foi encontrada" @@ -4011,6 +4012,10 @@ msgstr "o pow() com 3 argumentos requer números inteiros" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4211,7 +4216,7 @@ msgstr "o stop deve ser 1 ou 2" msgid "stop not reachable from start" msgstr "stop não está acessível a partir do início" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "a operação do fluxo não é compatível" @@ -4420,7 +4425,7 @@ msgid "unreadable attribute" msgstr "atributo ilegível" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo %q não suportado" @@ -4541,6 +4546,35 @@ 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 "%q must be 0-255" +#~ msgstr "%q deve ser entre 0-255" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q deve ser 1-255" + +#~ msgid "%q must be None or between 1 and len(report_descriptor)-1" +#~ msgstr "%q deve ser None ou entre 1 e len(report_descriptor)-1" + +#~ msgid "limit should be an int" +#~ msgstr "o limite deve ser um inteiro" + +#~ msgid "no available NIC" +#~ msgstr "não há uma Placa de Rede disponível" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "A porta não aceita portadora PWM. Em vez disso informe um pino, " +#~ "frequência e o ciclo de trabalho" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "A porta não aceita pinos ou frequência. Em vez disso, construa e passe um " +#~ "PWMOut Carrier" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "A instrução %d salta no pino" diff --git a/locale/sv.po b/locale/sv.po index a8603151d6..6f8287d0f2 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-07-24 15:35+0000\n" +"PO-Revision-Date: 2021-08-18 21:35+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.7.2-dev\n" +"X-Generator: Weblate 4.8-dev\n" #: main.c msgid "" @@ -99,6 +99,10 @@ msgstr "Indexet %q måste vara ett heltal, inte %s" msgid "%q length must be %q" msgstr "längden på %q måste vara %q" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "längden på %q måste vara >= 1" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q-listan måste vara en lista" @@ -111,14 +115,6 @@ msgstr "%q måste vara <=%d" msgid "%q must be %d-%d" msgstr "%q måste vara %d-%d" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q måste vara 0-255" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q måste vara 1-255" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "%q måste vara >= %d" @@ -135,10 +131,6 @@ msgstr "%q måste vara >= 0" msgid "%q must be >= 1" msgstr "%q måste vara >= 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "%q måste vara None eller mellan 1 och len(report_descriptor)-1" - #: py/argcheck.c msgid "%q must be a string" msgstr "%q måste vara en sträng" @@ -176,6 +168,10 @@ msgstr "%q ska vara en int" msgid "%q() takes %d positional arguments but %d were given" msgstr "% q () tar% d positionsargument men% d gavs" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q och %q måste vara lika långa" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -326,6 +322,10 @@ msgstr "'yield from' i async-funktion" msgid "'yield' outside function" msgstr "'yield' utanför funktion" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "(x,y) heltal krävs" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x måste vara mål för tilldelning" @@ -497,6 +497,10 @@ msgstr "Försök att tilldela %d block" msgid "Attempted heap allocation when VM not running." msgstr "Försök till heap-allokering när den virtuella maskinen inte är igång." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "Ljudkonvertering inte implementerad" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN används inte med lösenord" @@ -1204,11 +1208,6 @@ msgstr "Indata tar för lång tid" msgid "Input/output error" msgstr "Indata-/utdatafel" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "Saknar jmp_pin. Instruktion %d hoppar på pin" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1237,6 +1236,10 @@ msgstr "Otillräcklig autentisering" msgid "Insufficient encryption" msgstr "Otillräcklig kryptering" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "Intern ljudbuffert för liten" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Internt define-fel" @@ -1246,7 +1249,7 @@ msgstr "Internt define-fel" msgid "Internal error #%d" msgstr "Internt fel #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "Ogiltig %q" @@ -1526,6 +1529,16 @@ msgstr "Saknad first_out_pin. Instruktion %d skriver till pinnar" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "Saknad first_set_pin. Instruktion %d sätter pinnar" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "Saknar jmp_pin. Instruktion %d hoppar på pin" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "Fler än %d rapport-id stöds inte" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Måste vara en %q-subklass." @@ -1907,25 +1920,6 @@ msgstr "Plus eventuella moduler i filsystemet\n" msgid "Polygon needs at least 3 points" msgstr "Polygonen behöver minst 3 punkter" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "" -"Port accepterar inte PWM carrier. Ange pinne frekvens och arbetscykel " -"istället" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Porten accepterar inte pinne eller frekvens. Skapa och skicka en PWMOut " -"Carrier istället" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Prefixbufferten måste finnas på heap" @@ -2114,7 +2108,6 @@ msgid "Size not supported" msgstr "Storleken stöds inte" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "Sömnminne inte tillgängligt" @@ -2579,7 +2572,7 @@ msgid "argument name reused" msgstr "argumentnamn återanvänt" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "argument antal/typ matchar inte" @@ -3148,6 +3141,10 @@ msgstr "f-string: singel '}' är inte tillåten" msgid "file must be a file opened in byte mode" msgstr "filen måste vara en fil som öppnats i byte-läge" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "Filskrivning är inte tillgängligt" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "filsystemet måste tillhandahålla mount-metod" @@ -3435,6 +3432,10 @@ msgstr "ogiltig elementstorlek %d för bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "ogiltig element_size %d, måste vara, 1, 2 eller 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "Ogiltig exception" + #: extmod/modframebuf.c msgid "invalid format" msgstr "ogiltigt format" @@ -3472,6 +3473,10 @@ msgstr "ogiltig syntax för heltal med bas %d" msgid "invalid syntax for number" msgstr "ogiltig syntax för tal" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "Ogilitig källspårning" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() arg 1 måste vara en klass" @@ -3671,10 +3676,6 @@ msgstr "inget SD-kort" msgid "no active exception to reraise" msgstr "ingen aktiv exception för reraise" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "ingen tillgänglig NIC" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "ingen bindning för ickelokal hittad" @@ -3970,6 +3971,10 @@ msgstr "pow() med 3 argument kräver heltal" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4170,7 +4175,7 @@ msgstr "stop måste vara 1 eller 2" msgid "stop not reachable from start" msgstr "stop kan inte nås från start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream-åtgärd stöds inte" @@ -4379,7 +4384,7 @@ msgid "unreadable attribute" msgstr "attribut kan inte läsas" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "typ %q stöds inte" @@ -4500,6 +4505,35 @@ 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 "%q must be 0-255" +#~ msgstr "%q måste vara 0-255" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q måste vara 1-255" + +#~ msgid "%q must be None or between 1 and len(report_descriptor)-1" +#~ msgstr "%q måste vara None eller mellan 1 och len(report_descriptor)-1" + +#~ msgid "limit should be an int" +#~ msgstr "limit måste vara en int" + +#~ msgid "no available NIC" +#~ msgstr "ingen tillgänglig NIC" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Port accepterar inte PWM carrier. Ange pinne frekvens och arbetscykel " +#~ "istället" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Porten accepterar inte pinne eller frekvens. Skapa och skicka en PWMOut " +#~ "Carrier istället" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "Instruktion %d hoppar på pinne" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8f5e42127b..881c8969f2 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -101,6 +101,10 @@ msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s" msgid "%q length must be %q" msgstr "%q cháng dù bì xū wéi %q" +#: shared-bindings/usb_hid/Device.c +msgid "%q length must be >= 1" +msgstr "" + #: shared-bindings/vectorio/Polygon.c msgid "%q list must be a list" msgstr "%q lièbiǎo bìxū shì lièbiǎo" @@ -113,14 +117,6 @@ msgstr "%q bì xū <= %d" msgid "%q must be %d-%d" msgstr "%q bì xū wéi %d-%d" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 0-255" -msgstr "%q bì xū wéi 0-255" - -#: shared-bindings/usb_hid/Device.c -msgid "%q must be 1-255" -msgstr "%q bì xū wéi 1-255" - #: py/argcheck.c msgid "%q must be >= %d" msgstr "%q bì xū >= %d" @@ -137,10 +133,6 @@ msgstr "%q Bìxū > = 0" msgid "%q must be >= 1" msgstr "%q bìxū dàyú huò děngyú 1" -#: shared-bindings/usb_hid/Device.c -msgid "%q must be None or between 1 and len(report_descriptor)-1" -msgstr "%q bì xū wéi wú huò zài 1 hé len(report_descriptor)-1 zhī jiān" - #: py/argcheck.c msgid "%q must be a string" msgstr "%q bì xū shì yí gè zì fú chuàn" @@ -178,6 +170,10 @@ msgstr "%q yīnggāi shì yīgè int" msgid "%q() takes %d positional arguments but %d were given" msgstr "%q() cǎiyòng %d wèizhì cānshù, dàn gěi chū %d" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "" + #: ports/esp32s2/bindings/espidf/__init__.c ports/esp32s2/esp_error.c #, c-format msgid "%s error 0x%x" @@ -328,6 +324,10 @@ msgstr "Yì bù hán shù zhōng de 'yield from'" msgid "'yield' outside function" msgstr "'yield' wàibù gōngnéng" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x bìxū shì rènwù mùbiāo" @@ -499,6 +499,10 @@ msgstr "cháng shì fēn pèi %d kuài" msgid "Attempted heap allocation when VM not running." msgstr "dāng VM bú yùn xíng shí, cháng shì duī fēn pèi." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN wèi shǐ yòng mì mǎ" @@ -1207,11 +1211,6 @@ msgstr "Shūrù shíjiānguò zhǎng" msgid "Input/output error" msgstr "Shūrù/shūchū cuòwù" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1240,6 +1239,10 @@ msgstr "Rènzhèng bùzú" msgid "Insufficient encryption" msgstr "Jiāmì bùzú" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Nèibù dìngyì cuòwù" @@ -1249,7 +1252,7 @@ msgstr "Nèibù dìngyì cuòwù" msgid "Internal error #%d" msgstr "nèi bù cuò wù #%d" -#: shared-bindings/sdioio/SDCard.c +#: shared-bindings/sdioio/SDCard.c shared-module/usb_hid/Device.c msgid "Invalid %q" msgstr "wú xiào %q" @@ -1529,6 +1532,16 @@ msgstr "xiān lòu chū yǐn jiǎo. zhǐ lìng %d xiě rù yǐn jiǎo" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "quē shǎo dì yī zǔ yǐn jiǎo. zhǐ lìng %d shè zhì yǐn jiǎo" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + +#: shared-module/usb_hid/Device.c +#, c-format +msgid "More than %d report ids not supported" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Bìxū shì %q zi lèi." @@ -1909,22 +1922,6 @@ msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n" msgid "Polygon needs at least 3 points" msgstr "Duōbiānxíng zhìshǎo xūyào 3 diǎn" -#: ports/esp32s2/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " -"instead" -msgstr "Duānkǒu bù jiēshòu PWM zàibō. Tōngguò yǐn jiǎo, pínlǜ hé zhàn kōng bǐ" - -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nrf/common-hal/pulseio/PulseOut.c -#: ports/stm/common-hal/pulseio/PulseOut.c -msgid "" -"Port does not accept pins or frequency. Construct and pass a PWMOut Carrier " -"instead" -msgstr "" -"Duānkǒu bù jiēshòu yǐn jiǎo huò pínlǜ. Gòuzào bìng chuándì PWMOut zàibō" - #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" msgstr "Qiánzhuì huǎnchōng qū bìxū zài duī shàng" @@ -2113,7 +2110,6 @@ msgid "Size not supported" msgstr "bù zhī chí dà xiǎo" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "shuì mián jì yì bù kě yòng" @@ -2578,7 +2574,7 @@ msgid "argument name reused" msgstr "chóng fù shǐ yòng de cān shù míng chēng" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "cānshù biānhào/lèixíng bù pǐpèi" @@ -3148,6 +3144,10 @@ msgstr "f-string: bù yǔnxǔ shǐyòng dāngè '}'" msgid "file must be a file opened in byte mode" msgstr "wénjiàn bìxū shì zài zì jié móshì xià dǎkāi de wénjiàn" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "" + #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" msgstr "wénjiàn xìtǒng bìxū tígōng guà zài fāngfǎ" @@ -3435,6 +3435,10 @@ msgstr "wú xiào yuán jiàn dà xiǎo %d wéi bits_per_pixel %d\n" msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "wú xiào element_size %d, bì xū shì, 1, 2, huò 4" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "" + #: extmod/modframebuf.c msgid "invalid format" msgstr "wúxiào géshì" @@ -3472,6 +3476,10 @@ msgstr "jīshù wèi %d de zhěng shǔ de yǔfǎ wúxiào" msgid "invalid syntax for number" msgstr "wúxiào de hàomǎ yǔfǎ" +#: py/objexcept.c shared-bindings/traceback/__init__.c +msgid "invalid traceback" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "issubclass() cānshù 1 bìxū shì yīgè lèi" @@ -3669,10 +3677,6 @@ msgstr "méiyǒu SD kǎ" msgid "no active exception to reraise" msgstr "méiyǒu jīhuó de yìcháng lái chóngxīn píngjià" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "méiyǒu kěyòng de NIC" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "zhǎo bù dào fēi běndì de bǎng dìng" @@ -3967,6 +3971,10 @@ msgstr "pow() yǒu 3 cānshù xūyào zhěngshù" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4167,7 +4175,7 @@ msgstr "tíngzhǐ bìxū wèi 1 huò 2" msgid "stop not reachable from start" msgstr "tíngzhǐ wúfǎ cóng kāishǐ zhōng zhǎodào" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "bù zhīchí liú cāozuò" @@ -4376,7 +4384,7 @@ msgid "unreadable attribute" msgstr "bùkě dú shǔxìng" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "bù zhīchí %q lèixíng" @@ -4497,6 +4505,30 @@ 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 "%q must be 0-255" +#~ msgstr "%q bì xū wéi 0-255" + +#~ msgid "%q must be 1-255" +#~ msgstr "%q bì xū wéi 1-255" + +#~ msgid "%q must be None or between 1 and len(report_descriptor)-1" +#~ msgstr "%q bì xū wéi wú huò zài 1 hé len(report_descriptor)-1 zhī jiān" + +#~ msgid "no available NIC" +#~ msgstr "méiyǒu kěyòng de NIC" + +#~ msgid "" +#~ "Port does not accept PWM carrier. Pass a pin, frequency and duty cycle " +#~ "instead" +#~ msgstr "" +#~ "Duānkǒu bù jiēshòu PWM zàibō. Tōngguò yǐn jiǎo, pínlǜ hé zhàn kōng bǐ" + +#~ msgid "" +#~ "Port does not accept pins or frequency. Construct and pass a PWMOut " +#~ "Carrier instead" +#~ msgstr "" +#~ "Duānkǒu bù jiēshòu yǐn jiǎo huò pínlǜ. Gòuzào bìng chuándì PWMOut zàibō" + #~ msgid "Instruction %d jumps on pin" #~ msgstr "zhǐ lìng %d zài yǐn jiǎo shàng tiào zhuǎn" diff --git a/main.c b/main.c index 74a706e063..ec25bcbf08 100755 --- a/main.c +++ b/main.c @@ -645,11 +645,13 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { static const char * const boot_py_filenames[] = STRING_LIST("boot.py", "boot.txt"); bool skip_boot_output = false; + #ifdef CIRCUITPY_BOOT_OUTPUT_FILE + FIL file_pointer; + #endif if (ok_to_run) { #ifdef CIRCUITPY_BOOT_OUTPUT_FILE - FIL file_pointer; boot_output_file = &file_pointer; // Get the base filesystem. @@ -849,6 +851,7 @@ int __attribute__((used)) main(void) { serial_init(); #if CIRCUITPY_BLEIO + supervisor_bluetooth_enable_workflow(); supervisor_start_bluetooth(); #endif diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 291b515e80..810d86581b 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -322,6 +322,12 @@ SRC_C += \ reset.c \ timer_handler.c \ +# This is an OR because it filters to any 1s and then checks to see if it is not +# empty. +ifneq (,$(filter 1,$(CIRCUITPY_PWMIO) $(CIRCUITPY_AUDIOIO) $(CIRCUITPY_RGBMATRIX))) +SRC_C += shared_timers.c +endif + ifeq ($(CIRCUITPY_SDIOIO),1) SRC_C += ports/atmel-samd/sd_mmc/sd_mmc.c endif @@ -340,7 +346,7 @@ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(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/. +# because a few modules have files both in common-hal/ and shared-module/. # Doing a $(sort ...) removes duplicates as part of sorting. SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 7f1260973d..883fe0a192 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -157,7 +157,13 @@ void audio_dma_load_next_block(audio_dma_t *dma) { if (dma->loop) { audiosample_reset_buffer(dma->sample, dma->single_channel_output, dma->audio_channel); } else { - descriptor->DESCADDR.reg = 0; + if ((output_buffer_length == 0) && dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) { + // Nothing further to read and previous buffer is finished. + audio_dma_stop(dma); + } else { + // Break descriptor chain. + descriptor->DESCADDR.reg = 0; + } } } descriptor->BTCTRL.bit.VALID = true; @@ -214,21 +220,23 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, if (output_signed != samples_signed) { output_spacing = 1; max_buffer_length /= dma->spacing; - dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); - if (dma->first_buffer == NULL) { + } + + dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); + if (dma->first_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + dma->first_buffer_free = true; + if (!single_buffer) { + dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); + if (dma->second_buffer == NULL) { return AUDIO_DMA_MEMORY_ERROR; } - dma->first_buffer_free = true; - if (!single_buffer) { - dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); - if (dma->second_buffer == NULL) { - return AUDIO_DMA_MEMORY_ERROR; - } - } - dma->signed_to_unsigned = !output_signed && samples_signed; - dma->unsigned_to_signed = output_signed && !samples_signed; } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + dma->event_channel = 0xff; if (!single_buffer) { dma->second_descriptor = (DmacDescriptor *)m_malloc(sizeof(DmacDescriptor), false); @@ -265,13 +273,13 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, #ifdef SAM_D5X_E5X int irq = dma->event_channel < 4 ? EVSYS_0_IRQn + dma->event_channel : EVSYS_4_IRQn; + // Only disable and clear on SAMD51 because the SAMD21 shares EVSYS with ticks. + NVIC_DisableIRQ(irq); + NVIC_ClearPendingIRQ(irq); #else int irq = EVSYS_IRQn; #endif - NVIC_DisableIRQ(irq); - NVIC_ClearPendingIRQ(irq); - DmacDescriptor *first_descriptor = dma_descriptor(dma_channel); setup_audio_descriptor(first_descriptor, dma->beat_size, output_spacing, output_register_address); if (single_buffer) { @@ -366,7 +374,7 @@ STATIC void dma_callback_fun(void *arg) { audio_dma_load_next_block(dma); } -void evsyshandler_common(void) { +void audio_evsys_handler(void) { for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { audio_dma_t *dma = audio_dma_state[i]; if (dma == NULL) { @@ -380,26 +388,4 @@ void evsyshandler_common(void) { } } -#ifdef SAM_D5X_E5X -void EVSYS_0_Handler(void) { - evsyshandler_common(); -} -void EVSYS_1_Handler(void) { - evsyshandler_common(); -} -void EVSYS_2_Handler(void) { - evsyshandler_common(); -} -void EVSYS_3_Handler(void) { - evsyshandler_common(); -} -void EVSYS_4_Handler(void) { - evsyshandler_common(); -} -#else -void EVSYS_Handler(void) { - evsyshandler_common(); -} -#endif - #endif diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h index bc5beb3bf5..d06b589759 100644 --- a/ports/atmel-samd/audio_dma.h +++ b/ports/atmel-samd/audio_dma.h @@ -99,4 +99,6 @@ void audio_dma_background(void); uint8_t find_sync_event_channel_raise(void); +void audio_evsys_handler(void); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h index c792b01272..878b25f2f8 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h @@ -2,6 +2,7 @@ #define MICROPY_HW_MCU_NAME "samd21e18" #define MICROPY_HW_NEOPIXEL (&pin_PA15) +#define MICROPY_HW_NEOPIXEL_COUNT (2) #define IGNORE_PIN_PA01 1 #define IGNORE_PIN_PA02 1 diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk index a617947f9c..10a2f4ed37 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk @@ -14,12 +14,16 @@ CIRCUITPY_FULL_BUILD = 0 CIRCUITPY_ANALOGIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_BUSIO_SPI = 0 +CIRCUITPY_BUSIO_UART = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_GETPASS = 0 +CIRCUITPY_TRACEBACK = 0 + CIRCUITPY_PIXELBUF = 1 CIRCUITPY_BUSDEVICE = 1 diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h index f0748f35de..6a3f7a9687 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h @@ -16,3 +16,16 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 +// USD ID +#define IGNORE_PIN_PA18 1 + +// Hooked to the external crystal +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 + +// SWD only +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 + +// Not connected +#define IGNORE_PIN_PA28 1 diff --git a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h index 62883ad4a5..6be4f5606a 100644 --- a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h @@ -16,3 +16,11 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +// Not connected +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 + +// SWD only +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 diff --git a/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.h b/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.h index 6b1c9113be..41b88632d8 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.h +++ b/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.h @@ -1,5 +1,5 @@ // More than one revision of this board is available. -// This board specifies PCB Revision 10 +// This board specifies the most up to date PCB Revision #define MICROPY_HW_BOARD_NAME "BDMICRO VINA-D51" #define MICROPY_HW_MCU_NAME "samd51n20" diff --git a/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.mk b/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.mk index 13487413f4..9152cb6052 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.mk +++ b/ports/atmel-samd/boards/bdmicro_vina_d51/mpconfigboard.mk @@ -1,5 +1,5 @@ # More than one revision of this board is available. -# This board specifies PCB Revision 10 +# This board specifies the most up to date PCB Revision USB_VID = 0x31e2 USB_PID = 0x2021 @@ -10,5 +10,5 @@ CHIP_VARIANT = SAMD51N20A CHIP_FAMILY = samd51 QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "MX25L51245G","GD25S512MD" +EXTERNAL_FLASH_DEVICES = "MX25L12833F","MX25L51245G","GD25S512MD" LONGINT_IMPL = MPZ diff --git a/ports/atmel-samd/boards/bdmicro_vina_d51/pins.c b/ports/atmel-samd/boards/bdmicro_vina_d51/pins.c index e7595d9789..8a97842e20 100644 --- a/ports/atmel-samd/boards/bdmicro_vina_d51/pins.c +++ b/ports/atmel-samd/boards/bdmicro_vina_d51/pins.c @@ -1,5 +1,5 @@ // More than one revision of this board is available. -// This board specifies PCB Revision 10 +// This board specifies the most up to date PCB Revision #include "shared-bindings/board/__init__.h" @@ -59,6 +59,16 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA15) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB12) }, { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SDO), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SDI), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_I2S_FS_0), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCK_0), MP_ROM_PTR(&pin_PB16) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCK_0), MP_ROM_PTR(&pin_PB17) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PC17) }, { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PC18) }, { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PC19) }, @@ -73,14 +83,10 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_I2C1_SDA), MP_ROM_PTR(&pin_PA13) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_I2S_FS_0), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_I2S_MCK_0), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SCK_0), MP_ROM_PTR(&pin_PB16) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SDI), MP_ROM_PTR(&pin_PA22) }, - { MP_ROM_QSTR(MP_QSTR_I2S_SDO), MP_ROM_PTR(&pin_PA21) }, { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_LED_STATUS), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_LED_QSPI), MP_ROM_PTR(&pin_PC07) }, { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_PB14) }, { MP_ROM_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PC05) }, { MP_ROM_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PC06) }, diff --git a/ports/atmel-samd/boards/blm_badge/mpconfigboard.mk b/ports/atmel-samd/boards/blm_badge/mpconfigboard.mk index 8ba3ae94c3..a85a17890c 100644 --- a/ports/atmel-samd/boards/blm_badge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/blm_badge/mpconfigboard.mk @@ -14,6 +14,7 @@ CIRCUITPY_AUDIOIO = 1 CIRCUITPY_AUDIOBUSIO = 1 # Pins for I2SOut are not available. CIRCUITPY_AUDIOBUSIO_I2SOUT = 0 +CIRCUITPY_BUSIO_SPI = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 diff --git a/ports/atmel-samd/boards/cp_sapling_m0_revb/pins.c b/ports/atmel-samd/boards/cp_sapling_m0_revb/pins.c index b88b6869ef..dcc410572b 100644 --- a/ports/atmel-samd/boards/cp_sapling_m0_revb/pins.c +++ b/ports/atmel-samd/boards/cp_sapling_m0_revb/pins.c @@ -49,6 +49,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { 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_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index b125aca086..7db9491dd3 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -52,6 +52,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB22) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB00) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk index 196d36816f..4687ce32a0 100644 --- a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk @@ -9,3 +9,7 @@ CHIP_FAMILY = samd21 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + +# There are many pin definitions on this board; it doesn't quite fit on very large translations. +# So remove what might be least likely module to be used. +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h index 1842629266..5344e3c1ca 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h @@ -1,8 +1,11 @@ -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod SAMD51" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod SAMD51 Processor" #define MICROPY_HW_MCU_NAME "samd51j20" #define CIRCUITPY_MCU_FAMILY samd51 +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_PA23) + // On-board flash #define SPI_FLASH_MOSI_PIN &pin_PA09 #define SPI_FLASH_MISO_PIN &pin_PA10 diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk index 63d52382a2..3ae3d8f5a9 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk @@ -1,7 +1,7 @@ LD_FILE = boards/samd51x20-bootloader-external-flash.ld USB_VID = 0x1b4f USB_PID = 0x0020 # Used by uf2 bootloader -USB_PRODUCT = "SparkFun MicroMod SAMD51" +USB_PRODUCT = "SparkFun MicroMod SAMD51 Processor" USB_MANUFACTURER = "SparkFun Electronics" CHIP_VARIANT = SAMD51J20A diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c index 49411217d7..2233635084 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c @@ -1,97 +1,224 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * 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/board/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - // D (digital only) pins (D0,D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB04) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB05) }, + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A (ADC) pins (A0-A4) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB03) }, + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA23) }, // MicroMod LED (PA23) - // DAC - { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) - // G (General/BUS) pins (G0-G9) - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA14) }, - { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_PA14) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_PB31) }, - { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_PB15) }, - { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PB15) }, + // MicroMod +3.3V enable pin + { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR(&pin_PA19) }, // MicroMod 3.3V_EN (PA19) - // PWM pins (PWM0, PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PB02) }, + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_PB03) }, // MicroMod BATT_VIN/3 (PB03) - // AUD (audio) - { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PA21) }, - { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PA22) }, - { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB16) }, + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (SAMD51 has a dedicated HW RESETN pin) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA16) }, - { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA16) }, + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (not connected) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PA18) }, + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. See explicit ignores in mpconfigboard.h. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR(&pin_PA24) }, // MicroMod USB_D- (PA24) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR(&pin_PA25) }, // MicroMod USB_D+ (PA25) - // I2C2 - { MP_ROM_QSTR(MP_QSTR_SDA2), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_SCL2), MP_ROM_PTR(&pin_PA12) }, + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (not connected) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (not connected) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA07) }, + // MicroMod CAN pins + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB15) }, // MicroMod CAN_RX (PB15) + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB14) }, // MicroMod CAN_TX (PB14) - // Status LED - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA23) }, + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB31) }, - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB31) }, + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_PB31) }, // MicroMod UART_TX1 | CircuitPython TX (PB31) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_PB30) }, // MicroMod UART_RX1 | CircuitPython RX (PB30) + // { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR() }, // MicroMod RTS1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR() }, // MicroMod CTS1 (not connected) - // UART2 - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PA12) }, + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB31) }, // CircuitPython TX | MicroMod UART_TX1 (PB31) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB30) }, // CircuitPython RX | MicroMod UART_RX1 (PB30) + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_PA12) }, // MicroMod UART_TX2 (PA12) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_PA13) }, // MicroMod UART_RX2 (PA13) - // Board objects - { 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) }, + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_PA17) }, // MicroMod I2C_SDA | CircuitPython SDA (PA17) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PA16) }, // MicroMod I2C_SCL | CircuitPython SCL (PA16) + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA17) }, // CircuitPython SDA | MicroMod I2C_SDA (PA17) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA16) }, // CircuitPython SCL | MicroMod I2C_SCL (PA16) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PA18) }, // MicroMod I2C_INT (PA18) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_PA13) }, // MicroMod I2C_SDA1 (PA13) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_PA12) }, // MicroMod I2C_SCL1 (PA12) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_CIPO | CircuitPython CIPO (PA06) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_MISO | CircuitPython MISO (PA06) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (PA04) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_MOSI | CircuitPython MOSI (PA04) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (PA05) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_CS | CircuitPython CS (PA07) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython CIPO | MicroMod SPI_CIPO (PA06) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython MISO | MicroMod SPI_MISO (PA06) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA04) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (PA04) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) }, // CircuitPython MOSI | MicroMod SPI_MOSI (PA04) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (PA05) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA07) }, // CircuitPython CS | MicroMod SPI_CS (PA07) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_PA04) }, // MicroMod LED_DAT | SPI_COPI (PA04) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_PA05) }, // MicroMod LED_CLK | SPI_SCK (PA05) + + // MicroMod SDIO pins + // { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR() }, // MicroMod SDIO_SCK | SPI_SCK1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR() }, // MicroMod SDIO_CMD | SPI_COPI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR() }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR() }, // MicroMod SDIO_DATA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR() }, // MicroMod SDIO_DATA2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR() }, // MicroMod SDIO_DATA3 | SPI_CS1 (not connected) + + // MicroMod SPI1 pins + // { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR() }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR() }, // MicroMod SPI_MISO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR() }, // MicroMod SPI_COPI1 | SDIO_CMD (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR() }, // MicroMod SPI_MOSI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR() }, // MicroMod SPI_SCK1 | SDIO_SCK (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR() }, // MicroMod SPI_CS1 | SDIO_DATA3 (not connected) + + // MicroMod audio pins + { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_PB17) }, // MicroMod AUD_MCLK (PB17) + { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA20) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (PB16) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_PA20) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_PB16) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (PB16) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_PA20) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (PB16) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_PA20) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (PA20) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (PB16) + + // MicroMod SWD pins + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) }, // MicroMod SWDIO (PA31) + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) }, // MicroMod SWDCK (PA30) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not connected) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // MicroMod A0 (PA02) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, // MicroMod A1 (PB00) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PB01) }, // MicroMod PWM0 (PB01) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PB02) }, // MicroMod PWM1 (PB02) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB04) }, // MicroMod D0 (PB04) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB05) }, // MicroMod D1 | CAM_TRIG (PB05) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PB06) }, // MicroMod G0 | BUS0 (PB06) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PB07) }, // MicroMod G1 | BUS1 (PB07) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PB08) }, // MicroMod G2 | BUS2 (PB08) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PB09) }, // MicroMod G3 | BUS3 (PB09) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PB10) }, // MicroMod G4 | BUS4 (PB10) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PB11) }, // MicroMod G5 | BUS5 (PB11) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PB12) }, // MicroMod G6 | BUS6 (PB12) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_PB13) }, // MicroMod G7 | BUS7 (PB13) + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_PA14) }, // MicroMod G8 (PA14) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_PA15) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (PA15) + // { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR() }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (not connected) + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PA27) }, // MicroMod G11 | SWO (PA27) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_PB06) }, // MicroMod BUS0 | G0 (PB06) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_PB07) }, // MicroMod BUS1 | G1 (PB07) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_PB08) }, // MicroMod BUS2 | G2 (PB08) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_PB09) }, // MicroMod BUS3 | G3 (PB09) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_PB10) }, // MicroMod BUS4 | G4 (PB10) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_PB11) }, // MicroMod BUS5 | G5 (PB11) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_PB12) }, // MicroMod BUS6 | G6 (PB12) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_PB13) }, // MicroMod BUS7 | G7 (PB13) + + // MicroMod differential ADC input pins + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_PA15) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (PA15) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR() }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (not connected) + + // MicroMod camera pins + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_PA21) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (PA21) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_PA22) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (PA22) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_PB05) }, // MicroMod CAM_TRIG | D1 (PB05) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_PA15 }, // MicroMod CAM_HSYNC | ADC_D- | G9 (PA15) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR() }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (not connected) + + // Module-specific aliases (not part of the MicroMod spec) + { MP_ROM_QSTR(MP_QSTR_HOST_ENABLE), MP_ROM_PTR(&pin_PA27) }, // HOST_ENABLE | G11 | SWO (PA27) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 2488b7b922..a434e2541b 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -71,7 +71,7 @@ void i2sout_reset(void) { // Make sure the I2S peripheral is running so we can see if the resources we need are free. #ifdef SAM_D5X_E5X - // Connect the clock units to the 2mhz clock. It can't disable without it. + // Connect the clock units to the 2MHz clock. It can't disable without it. connect_gclk_to_peripheral(5, I2S_GCLK_ID_0); connect_gclk_to_peripheral(5, I2S_GCLK_ID_1); #endif @@ -83,7 +83,7 @@ void i2sout_reset(void) { // Make sure the I2S peripheral is running so we can see if the resources we need are free. #ifdef SAM_D5X_E5X - // Connect the clock units to the 2mhz clock by default. They can't reset without it. + // Connect the clock units to the 2MHz clock by default. They can't reset without it. disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_0); disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_1); @@ -222,7 +222,6 @@ void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) { reset_pin_number(self->word_select->number); self->word_select = NULL; reset_pin_number(self->data->number); - self->data = NULL; } void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, @@ -288,7 +287,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, I2S->TXCTRL.reg = serctrl; #endif - // The DFLL is always a 48mhz clock + // The DFLL is always a 48MHz clock enable_clock_generator(self->gclk, CLOCK_48MHZ, divisor); connect_gclk_to_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); diff --git a/ports/atmel-samd/common-hal/canio/Listener.c b/ports/atmel-samd/common-hal/canio/Listener.c index adb3048496..ce09764757 100644 --- a/ports/atmel-samd/common-hal/canio/Listener.c +++ b/ports/atmel-samd/common-hal/canio/Listener.c @@ -30,6 +30,8 @@ #include "py/obj.h" #include "py/runtime.h" +#include "lib/utils/interrupt_char.h" + #include "common-hal/canio/__init__.h" #include "common-hal/canio/Listener.h" #include "shared-bindings/canio/Listener.h" @@ -356,6 +358,11 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { if (supervisor_ticks_ms64() > deadline) { return NULL; } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return NULL; + } } while (!common_hal_canio_listener_in_waiting(self)); } int index = self->hw->RXFS.bit.F0GI; diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 49cef92478..507db7e437 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -272,6 +272,9 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t *self) { uint32_t mask = 1 << self->channel; EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos; + #ifdef SAMD21 + rtc_end_pulse(); + #endif } void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, @@ -299,6 +302,9 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos; EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos; + #ifdef SAMD21 + rtc_start_pulse(); + #endif pulsein_set_config(self, true); } diff --git a/ports/atmel-samd/common-hal/pwmio/PWMOut.c b/ports/atmel-samd/common-hal/pwmio/PWMOut.c index 4f6661b55d..fa6a2d3f47 100644 --- a/ports/atmel-samd/common-hal/pwmio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pwmio/PWMOut.c @@ -31,15 +31,15 @@ #include "common-hal/pwmio/PWMOut.h" #include "shared-bindings/pwmio/PWMOut.h" #include "shared-bindings/microcontroller/Processor.h" +#include "shared_timers.h" #include "timer_handler.h" #include "atmel_start_pins.h" #include "hal/utils/include/utils_repeat_macro.h" +#include "samd/pins.h" #include "samd/timers.h" #include "supervisor/shared/translate.h" -#include "samd/pins.h" - #undef ENABLE #define _TCC_SIZE(unused, n) TCC##n##_SIZE, @@ -60,24 +60,6 @@ uint8_t tcc_channels[3]; // Set by pwmout_reset() to {0xf0, 0xfc, 0xfc} initia uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, 0xfc} initially. #endif -static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; - -STATIC void timer_refcount(int index, bool is_tc, int increment) { - if (is_tc) { - never_reset_tc_or_tcc[index] += increment; - } else { - never_reset_tc_or_tcc[TC_INST_NUM + index] += increment; - } -} - -void timer_never_reset(int index, bool is_tc) { - timer_refcount(index, is_tc, 1); -} - -void timer_reset_ok(int index, bool is_tc) { - timer_refcount(index, is_tc, -1); -} - void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { timer_never_reset(self->timer->index, self->timer->is_tc); @@ -95,34 +77,11 @@ void pwmout_reset(void) { target_tcc_frequencies[i] = 0; tcc_refcount[i] = 0; } - Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; for (int i = 0; i < TCC_INST_NUM; i++) { - if (never_reset_tc_or_tcc[TC_INST_NUM + i] > 0) { + if (!timer_ok_to_reset(i, false)) { continue; } - // Disable the module before resetting it. - if (tccs[i]->CTRLA.bit.ENABLE == 1) { - tccs[i]->CTRLA.bit.ENABLE = 0; - while (tccs[i]->SYNCBUSY.bit.ENABLE == 1) { - } - } - uint8_t mask = 0xff; - for (uint8_t j = 0; j < tcc_cc_num[i]; j++) { - mask <<= 1; - } - tcc_channels[i] = mask; - tccs[i]->CTRLA.bit.SWRST = 1; - while (tccs[i]->CTRLA.bit.SWRST == 1) { - } - } - Tc *tcs[TC_INST_NUM] = TC_INSTS; - for (int i = 0; i < TC_INST_NUM; i++) { - if (never_reset_tc_or_tcc[i] > 0) { - continue; - } - tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; - while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) { - } + tcc_channels[i] = 0xff << tcc_cc_num[i]; } } diff --git a/ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.c b/ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.c index aa0bd78275..eca3757f20 100644 --- a/ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.c +++ b/ports/atmel-samd/common-hal/rgbmatrix/RGBMatrix.c @@ -29,6 +29,7 @@ #include "common-hal/rgbmatrix/RGBMatrix.h" #include "samd/timers.h" +#include "shared_timers.h" #include "timer_handler.h" void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) { diff --git a/ports/atmel-samd/shared_timers.c b/ports/atmel-samd/shared_timers.c new file mode 100644 index 0000000000..f07bd372da --- /dev/null +++ b/ports/atmel-samd/shared_timers.c @@ -0,0 +1,84 @@ +/* + * 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 + +#include "samd/timers.h" + +#include "shared_timers.h" + +static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; + +static void timer_refcount(int index, bool is_tc, int increment) { + if (is_tc) { + never_reset_tc_or_tcc[index] += increment; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + index] += increment; + } +} + +void timer_never_reset(int index, bool is_tc) { + timer_refcount(index, is_tc, 1); +} + +void timer_reset_ok(int index, bool is_tc) { + timer_refcount(index, is_tc, -1); +} + +bool timer_ok_to_reset(int index, bool is_tc) { + if (is_tc) { + return never_reset_tc_or_tcc[index] == 0; + } + return never_reset_tc_or_tcc[TC_INST_NUM + index] == 0; +} + +void reset_timers(void) { + // Reset all timers + Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; + for (int i = 0; i < TCC_INST_NUM; i++) { + if (!timer_ok_to_reset(i, false)) { + continue; + } + // Disable the module before resetting it. + if (tccs[i]->CTRLA.bit.ENABLE == 1) { + tccs[i]->CTRLA.bit.ENABLE = 0; + while (tccs[i]->SYNCBUSY.bit.ENABLE == 1) { + } + } + tccs[i]->CTRLA.bit.SWRST = 1; + while (tccs[i]->CTRLA.bit.SWRST == 1) { + } + } + Tc *tcs[TC_INST_NUM] = TC_INSTS; + for (int i = 0; i < TC_INST_NUM; i++) { + if (!timer_ok_to_reset(i, true)) { + continue; + } + tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; + while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) { + } + } +} diff --git a/ports/cxd56/common-hal/busio/OneWire.h b/ports/atmel-samd/shared_timers.h similarity index 74% rename from ports/cxd56/common-hal/busio/OneWire.h rename to ports/atmel-samd/shared_timers.h index 17c1b22375..88edd3aa12 100644 --- a/ports/cxd56/common-hal/busio/OneWire.h +++ b/ports/atmel-samd/shared_timers.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright 2019 Sony Semiconductor Solutions Corporation + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,11 +23,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_TIMERS_H +#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_TIMERS_H -#ifndef MICROPY_INCLUDED_CXD56_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_CXD56_COMMON_HAL_BUSIO_ONEWIRE_H +#include -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +void timer_never_reset(int index, bool is_tc); +void timer_reset_ok(int index, bool is_tc); +bool timer_ok_to_reset(int index, bool is_tc); +void reset_timers(void); -#endif // MICROPY_INCLUDED_CXD56_COMMON_HAL_BUSIO_ONEWIRE_H +#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_TIMERS_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index c03b79ce4f..4aa9daa3e9 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -77,6 +77,7 @@ #include "samd/dma.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/rtc/__init__.h" +#include "shared_timers.h" #include "reset.h" #include "supervisor/shared/safe_mode.h" @@ -91,26 +92,19 @@ #if CIRCUITPY_PEW #include "common-hal/_pew/PewPew.h" #endif -volatile bool hold_interrupt = false; +static volatile bool sleep_ok = true; #ifdef SAMD21 -static void rtc_set_continuous(bool continuous) { - while (RTC->MODE0.STATUS.bit.SYNCBUSY) { - ; - } - RTC->MODE0.READREQ.reg = (continuous ? RTC_READREQ_RCONT : 0) | 0x0010; - while (RTC->MODE0.STATUS.bit.SYNCBUSY) { - ; - } -} +static uint8_t _tick_event_channel = 0; +// Sleeping requires a register write that can stall interrupt handling. Turning +// off sleeps allows for more accurate interrupt timing. (Python still thinks +// it is sleeping though.) void rtc_start_pulse(void) { - rtc_set_continuous(true); - hold_interrupt = true; + sleep_ok = false; } void rtc_end_pulse(void) { - hold_interrupt = false; - rtc_set_continuous(false); + sleep_ok = true; } #endif @@ -161,6 +155,20 @@ static void save_usb_clock_calibration(void) { } #endif +static void rtc_continuous_mode(void) { + #ifdef SAMD21 + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + RTC->MODE0.READREQ.reg = RTC_READREQ_RCONT | 0x0010; + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + // Do the first request and wait for it. + RTC->MODE0.READREQ.reg = RTC_READREQ_RREQ | RTC_READREQ_RCONT | 0x0010; + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + #endif +} + static void rtc_init(void) { #ifdef SAMD21 _gclk_enable_channel(RTC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK2_Val); @@ -168,9 +176,17 @@ static void rtc_init(void) { while (RTC->MODE0.CTRL.bit.SWRST != 0) { } + // Turn on periodic events to use as tick. We control whether it interrupts + // us with the EVSYS INTEN register. + RTC->MODE0.EVCTRL.reg = RTC_MODE0_EVCTRL_PEREO2; + RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_ENABLE | RTC_MODE0_CTRL_MODE_COUNT32 | RTC_MODE0_CTRL_PRESCALER_DIV2; + + // Turn on continuous sync of the count register. This will speed up all + // tick reads. + rtc_continuous_mode(); #endif #ifdef SAM_D5X_E5X hri_mclk_set_APBAMASK_RTC_bit(MCLK); @@ -347,6 +363,9 @@ void reset_port(void) { #if CIRCUITPY_PWMIO pwmout_reset(); #endif + #if CIRCUITPY_PWMIO || CIRCUITPY_AUDIOIO + reset_timers(); + #endif #if CIRCUITPY_ANALOGIO analogin_reset(); @@ -363,6 +382,9 @@ void reset_port(void) { #endif reset_event_system(); + #ifdef SAMD21 + _tick_event_channel = EVSYS_SYNCH_NUM; + #endif reset_all_pins(); @@ -430,21 +452,14 @@ uint32_t port_get_saved_word(void) { // TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain // is enabled. static volatile uint64_t overflowed_ticks = 0; -#ifdef SAMD21 -static volatile bool _ticks_enabled = false; -#endif static uint32_t _get_count(uint64_t *overflow_count) { #ifdef SAM_D5X_E5X while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) { } #endif - #ifdef SAMD21 - // Request a read so we don't stall the bus later. See section 14.3.1.5 Read Request - RTC->MODE0.READREQ.reg = RTC_READREQ_RREQ | 0x0010; - while (RTC->MODE0.STATUS.bit.SYNCBUSY != 0) { - } - #endif + // SAMD21 does continuous sync so we don't need to wait here. + // Disable interrupts so we can grab the count and the overflow. common_hal_mcu_disable_interrupts(); uint32_t count = RTC->MODE0.COUNT.reg; @@ -458,29 +473,6 @@ static uint32_t _get_count(uint64_t *overflow_count) { volatile bool _woken_up; -static void _port_interrupt_after_ticks(uint32_t ticks) { - uint32_t current_ticks = _get_count(NULL); - if (ticks > 1 << 28) { - // We'll interrupt sooner with an overflow. - return; - } - #ifdef SAMD21 - if (hold_interrupt) { - return; - } - #endif - uint32_t target = current_ticks + (ticks << 4); - RTC->MODE0.COMP[0].reg = target; - #ifdef SAM_D5X_E5X - while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COMP0)) != 0) { - } - #endif - RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; - RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; - current_ticks = _get_count(NULL); - _woken_up = current_ticks >= target; -} - void RTC_Handler(void) { uint32_t intflag = RTC->MODE0.INTFLAG.reg; if (intflag & RTC_MODE0_INTFLAG_OVF) { @@ -497,19 +489,10 @@ void RTC_Handler(void) { } #endif if (intflag & RTC_MODE0_INTFLAG_CMP0) { - // Clear the interrupt because we may have hit a sleep and _ticks_enabled + // Clear the interrupt because we may have hit a sleep RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; _woken_up = true; - #ifdef SAMD21 - if (_ticks_enabled) { - // Do things common to all ports when the tick occurs. - supervisor_tick(); - // Check _ticks_enabled again because a tick handler may have turned it off. - if (_ticks_enabled) { - _port_interrupt_after_ticks(1); - } - } - #endif + // SAMD21 ticks are handled by EVSYS #ifdef SAM_D5X_E5X RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; #endif @@ -526,6 +509,39 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { return overflow_count + current_ticks / 16; } +void evsyshandler_common(void) { + #ifdef SAMD21 + if (_tick_event_channel < EVSYS_SYNCH_NUM && event_interrupt_active(_tick_event_channel)) { + supervisor_tick(); + } + #endif + #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO + audio_evsys_handler(); + #endif +} + +#ifdef SAM_D5X_E5X +void EVSYS_0_Handler(void) { + evsyshandler_common(); +} +void EVSYS_1_Handler(void) { + evsyshandler_common(); +} +void EVSYS_2_Handler(void) { + evsyshandler_common(); +} +void EVSYS_3_Handler(void) { + evsyshandler_common(); +} +void EVSYS_4_Handler(void) { + evsyshandler_common(); +} +#else +void EVSYS_Handler(void) { + evsyshandler_common(); +} +#endif + // Enable 1/1024 second tick. void port_enable_tick(void) { #ifdef SAM_D5X_E5X @@ -533,9 +549,23 @@ void port_enable_tick(void) { RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2; #endif #ifdef SAMD21 - // TODO: Switch to using the PER *event* from the RTC to generate an interrupt via EVSYS. - _ticks_enabled = true; - _port_interrupt_after_ticks(1); + // SAMD21 ticks won't survive port_reset(). This *should* be ok since it'll + // be triggered by ticks and no Python will be running. + if (_tick_event_channel >= EVSYS_SYNCH_NUM) { + turn_on_event_system(); + _tick_event_channel = find_sync_event_channel(); + } + // This turns on both the event detected interrupt (EVD) and overflow (OVR). + init_event_channel_interrupt(_tick_event_channel, CORE_GCLK, EVSYS_ID_GEN_RTC_PER_2); + // Disable overflow interrupt because we ignore it. + if (_tick_event_channel >= 8) { + uint8_t value = 1 << (_tick_event_channel - 8); + EVSYS->INTENCLR.reg = EVSYS_INTENSET_OVRp8(value); + } else { + uint8_t value = 1 << _tick_event_channel; + EVSYS->INTENCLR.reg = EVSYS_INTENSET_OVR(value); + } + NVIC_EnableIRQ(EVSYS_IRQn); #endif } @@ -545,21 +575,48 @@ void port_disable_tick(void) { RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2; #endif #ifdef SAMD21 - _ticks_enabled = false; - RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; + if (_tick_event_channel >= 8) { + uint8_t value = 1 << (_tick_event_channel - 8); + EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVDp8(value); + } else { + uint8_t value = 1 << _tick_event_channel; + EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVD(value); + } #endif } -// 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) { + uint32_t current_ticks = _get_count(NULL); + if (ticks > 1 << 28) { + // We'll interrupt sooner with an overflow. + return; + } #ifdef SAMD21 - if (_ticks_enabled) { + if (!sleep_ok) { return; } #endif - _port_interrupt_after_ticks(ticks); + + uint32_t target = current_ticks + (ticks << 4); + #ifdef SAMD21 + // Try and avoid a bus stall when writing COMP by checking for an obvious + // existing sync. + while (RTC->MODE0.STATUS.bit.SYNCBUSY == 1) { + } + #endif + // Writing the COMP register can take up to 180us to synchronize. During + // this time, the bus will stall and no interrupts will be serviced. + RTC->MODE0.COMP[0].reg = target; + #ifdef SAM_D5X_E5X + while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COMP0)) != 0) { + } + #endif + RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; + RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; + // Set continuous mode again because setting COMP may disable it. + rtc_continuous_mode(); + current_ticks = _get_count(NULL); + _woken_up = current_ticks >= target; } void port_idle_until_interrupt(void) { @@ -571,7 +628,7 @@ void port_idle_until_interrupt(void) { } #endif common_hal_mcu_disable_interrupts(); - if (!tud_task_event_ready() && !hold_interrupt && !_woken_up) { + if (!tud_task_event_ready() && sleep_ok && !_woken_up) { __DSB(); __WFI(); } diff --git a/ports/atmel-samd/timer_handler.h b/ports/atmel-samd/timer_handler.h index 34efda4d9e..517ad768ba 100644 --- a/ports/atmel-samd/timer_handler.h +++ b/ports/atmel-samd/timer_handler.h @@ -36,8 +36,4 @@ void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler); void shared_timer_handler(bool is_tc, uint8_t index); -// implementation of these functions is in PWMOut.c -void timer_never_reset(int index, bool is_tc); -void timer_reset_ok(int index, bool is_tc); - #endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H diff --git a/ports/cxd56/common-hal/busio/SPI.c b/ports/cxd56/common-hal/busio/SPI.c index ff834f7f38..ea481e136d 100644 --- a/ports/cxd56/common-hal/busio/SPI.c +++ b/ports/cxd56/common-hal/busio/SPI.c @@ -132,7 +132,8 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size } bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { - SPI_EXCHANGE(self->spi_dev, NULL, data, len); + memset(data, write_value, len); + SPI_EXCHANGE(self->spi_dev, data, data, len); return true; } diff --git a/ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h b/ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h index 40a7add36b..a040fe70e0 100644 --- a/ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h +++ b/ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h @@ -29,8 +29,8 @@ #define MICROPY_HW_BOARD_NAME "Adafruit FunHouse" #define MICROPY_HW_MCU_NAME "ESP32S2" -#define MICROPY_HW_APA_MOSI (&pin_GPIO14) -#define MICROPY_HW_APA_SCK (&pin_GPIO15) +#define MICROPY_HW_APA102_MOSI (&pin_GPIO14) +#define MICROPY_HW_APA102_SCK (&pin_GPIO15) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) diff --git a/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/board.c b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/board.c new file mode 100644 index 0000000000..e40b6335bc --- /dev/null +++ b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/board.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.h b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.h new file mode 100644 index 0000000000..1af2d2420c --- /dev/null +++ b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +// Same setup as the Saola board but with no Neopixel on board + +#define MICROPY_HW_BOARD_NAME "ESP 12k NodeMCU" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +// #define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk new file mode 100644 index 0000000000..08baf474ee --- /dev/null +++ b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x612B +USB_PID = 0x80A7 +USB_PRODUCT = "ESP 12k NodeMCU" +USB_MANUFACTURER = "Ai-Thinker" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/pins.c b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/pins.c new file mode 100644 index 0000000000..a8ca8ba3ed --- /dev/null +++ b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/pins.c @@ -0,0 +1,48 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + // { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/sdkconfig b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/sdkconfig new file mode 100644 index 0000000000..1a86435efc --- /dev/null +++ b/ports/esp32s2/boards/ai_thinker_esp_12k_nodemcu/sdkconfig @@ -0,0 +1,33 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=4194304 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/pins.c b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c index cfc4ef6223..96dd940985 100644 --- a/ports/esp32s2/boards/atmegazero_esp32s2/pins.c +++ b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c @@ -64,9 +64,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO40) }, diff --git a/ports/esp32s2/boards/crumpspace_crumps2/board.c b/ports/esp32s2/boards/crumpspace_crumps2/board.c new file mode 100644 index 0000000000..e40b6335bc --- /dev/null +++ b/ports/esp32s2/boards/crumpspace_crumps2/board.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/atmel-samd/common-hal/busio/OneWire.h b/ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.h similarity index 78% rename from ports/atmel-samd/common-hal/busio/OneWire.h rename to ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.h index a09a44c262..cda4e0e534 100644 --- a/ports/atmel-samd/common-hal/busio/OneWire.h +++ b/ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Scott Shawcroft + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +24,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H +// Micropython setup -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +#define MICROPY_HW_BOARD_NAME "CrumpS2" +#define MICROPY_HW_MCU_NAME "ESP32S2" -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.mk b/ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.mk new file mode 100644 index 0000000000..8eea211d6a --- /dev/null +++ b/ports/esp32s2/boards/crumpspace_crumps2/mpconfigboard.mk @@ -0,0 +1,22 @@ +USB_VID = 0x1209 +USB_PID = 0x3141 +USB_PRODUCT = "CrumpS2" +USB_MANUFACTURER = "CrumpSpace" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_BITBANG_APA102 = 1 + +CIRCUITPY_MODULE=wrover + +# Include these Python libraries in firmware. +# FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar diff --git a/ports/esp32s2/boards/crumpspace_crumps2/pins.c b/ports/esp32s2/boards/crumpspace_crumps2/pins.c new file mode 100644 index 0000000000..278f1ab7bd --- /dev/null +++ b/ports/esp32s2/boards/crumpspace_crumps2/pins.c @@ -0,0 +1,53 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_GPIO40) }, // APA102 + + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_APA102_SCK), MP_ROM_PTR(&pin_GPIO45) }, // APA102 + + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/crumpspace_crumps2/sdkconfig b/ports/esp32s2/boards/crumpspace_crumps2/sdkconfig new file mode 100644 index 0000000000..04b487625d --- /dev/null +++ b/ports/esp32s2/boards/crumpspace_crumps2/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="CrumpS2" +# end of LWIP diff --git a/ports/esp32s2/boards/espressif_kaluga_1.3/mpconfigboard.mk b/ports/esp32s2/boards/espressif_kaluga_1.3/mpconfigboard.mk index 52c63cb9c7..2dce038819 100644 --- a/ports/esp32s2/boards/espressif_kaluga_1.3/mpconfigboard.mk +++ b/ports/esp32s2/boards/espressif_kaluga_1.3/mpconfigboard.mk @@ -14,10 +14,4 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -# We only have enough endpoints available in hardware to -# enable ONE of these at a time. -CIRCUITPY_USB_MIDI = 1 -CIRCUITPY_USB_HID = 0 -CIRCUITPY_USB_VENDOR = 0 - CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk index 52c63cb9c7..2dce038819 100644 --- a/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk +++ b/ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.mk @@ -14,10 +14,4 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -# We only have enough endpoints available in hardware to -# enable ONE of these at a time. -CIRCUITPY_USB_MIDI = 1 -CIRCUITPY_USB_HID = 0 -CIRCUITPY_USB_VENDOR = 0 - CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/gravitech_cucumber_m/board.c b/ports/esp32s2/boards/gravitech_cucumber_m/board.c new file mode 100644 index 0000000000..ec84d3209c --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_m/board.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h b/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h new file mode 100644 index 0000000000..5406f88f01 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Gravitech Cucumber M" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.mk b/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.mk new file mode 100644 index 0000000000..3e1fa2526a --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303A +USB_PID = 0x80A4 +USB_PRODUCT = "Cucumber M" +USB_MANUFACTURER = "Gravitech" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wroom diff --git a/ports/esp32s2/boards/gravitech_cucumber_m/pins.c b/ports/esp32s2/boards/gravitech_cucumber_m/pins.c new file mode 100644 index 0000000000..0d8bde1919 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_m/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/gravitech_cucumber_m/sdkconfig b/ports/esp32s2/boards/gravitech_cucumber_m/sdkconfig new file mode 100644 index 0000000000..af73f6d885 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_m/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_m" +# end of LWIP diff --git a/ports/esp32s2/boards/gravitech_cucumber_ms/board.c b/ports/esp32s2/boards/gravitech_cucumber_ms/board.c new file mode 100644 index 0000000000..ec84d3209c --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_ms/board.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h b/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h new file mode 100644 index 0000000000..c0b6fee029 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Gravitech Cucumber MS" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.mk b/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.mk new file mode 100644 index 0000000000..7a0d84a311 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303A +USB_PID = 0x80A7 +USB_PRODUCT = "Cucumber MS" +USB_MANUFACTURER = "Gravitech" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wroom diff --git a/ports/esp32s2/boards/gravitech_cucumber_ms/pins.c b/ports/esp32s2/boards/gravitech_cucumber_ms/pins.c new file mode 100644 index 0000000000..980e153995 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_ms/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/gravitech_cucumber_ms/sdkconfig b/ports/esp32s2/boards/gravitech_cucumber_ms/sdkconfig new file mode 100644 index 0000000000..cbdd787aa7 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_ms/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_ms" +# end of LWIP diff --git a/ports/esp32s2/boards/gravitech_cucumber_r/board.c b/ports/esp32s2/boards/gravitech_cucumber_r/board.c new file mode 100644 index 0000000000..ec84d3209c --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_r/board.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h b/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h new file mode 100644 index 0000000000..5d51ff002f --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Gravitech Cucumber R" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.mk b/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.mk new file mode 100644 index 0000000000..018742b469 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303A +USB_PID = 0x80A1 +USB_PRODUCT = "Cucumber R" +USB_MANUFACTURER = "Gravitech" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/gravitech_cucumber_r/pins.c b/ports/esp32s2/boards/gravitech_cucumber_r/pins.c new file mode 100644 index 0000000000..0d8bde1919 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_r/pins.c @@ -0,0 +1,49 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/gravitech_cucumber_r/sdkconfig b/ports/esp32s2/boards/gravitech_cucumber_r/sdkconfig new file mode 100644 index 0000000000..3862b27003 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_r/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_r" +# end of LWIP diff --git a/ports/esp32s2/boards/gravitech_cucumber_rs/board.c b/ports/esp32s2/boards/gravitech_cucumber_rs/board.c new file mode 100644 index 0000000000..ec84d3209c --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_rs/board.c @@ -0,0 +1,51 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO43); + common_hal_never_reset_pin(&pin_GPIO44); + #endif /* DEBUG */ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h b/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h new file mode 100644 index 0000000000..14bc06f0e3 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Gravitech Cucumber RS" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.mk b/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.mk new file mode 100644 index 0000000000..807dcaabbf --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303A +USB_PID = 0x800D +USB_PRODUCT = "Cucumber RS" +USB_MANUFACTURER = "Gravitech" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/gravitech_cucumber_rs/pins.c b/ports/esp32s2/boards/gravitech_cucumber_rs/pins.c new file mode 100644 index 0000000000..980e153995 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_rs/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/gravitech_cucumber_rs/sdkconfig b/ports/esp32s2/boards/gravitech_cucumber_rs/sdkconfig new file mode 100644 index 0000000000..bc8328d1f1 --- /dev/null +++ b/ports/esp32s2/boards/gravitech_cucumber_rs/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_rs" +# end of LWIP diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h index 47bcde7e93..b8d6707b7c 100644 --- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h @@ -28,8 +28,6 @@ #define MICROPY_HW_BOARD_NAME "microS2" #define MICROPY_HW_MCU_NAME "ESP32S2" -#define MICROPY_HW_LED (&pin_GPIO21) -#define MICROPY_HW_BUTTON (&pin_GPIO0) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33) // Default bus pins diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/board.c b/ports/esp32s2/boards/morpheans_morphesp-240/board.c new file mode 100644 index 0000000000..3dcf6d2465 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/board.c @@ -0,0 +1,227 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + +// From Arduino-ST7789 library https://github.com/ananevilya/Arduino-ST7789-Library/blob/master/Arduino_ST7789.cpp +#define ST7789_TFTWIDTH 240 +#define ST7789_TFTHEIGHT 240 + +#define ST7789_240x240_XSTART 0 +#define ST7789_240x240_YSTART 0 + +#define ST7789_NOP 0x00 +#define ST7789_SWRESET 0x01 +#define ST7789_RDDID 0x04 +#define ST7789_RDDST 0x09 + +#define ST7789_SLPIN 0x10 +#define ST7789_SLPOUT 0x11 +#define ST7789_PTLON 0x12 +#define ST7789_NORON 0x13 + +#define ST7789_INVOFF 0x20 +#define ST7789_INVON 0x21 +#define ST7789_DISPOFF 0x28 +#define ST7789_DISPON 0x29 +#define ST7789_CASET 0x2A +#define ST7789_RASET 0x2B +#define ST7789_RAMWR 0x2C +#define ST7789_RAMRD 0x2E + +#define ST7789_PTLAR 0x30 +#define ST7789_COLMOD 0x3A +#define ST7789_MADCTL 0x36 +#define ST7789_VSCSAD 0x37 +#define ST7789_PORCTRL 0xB2 +#define ST7789_GCTRL 0xB7 +#define ST7789_VCOMS 0xBB +#define ST7789_LCMCTRL 0xC0 +#define ST7789_IDSET 0xC1 +#define ST7789_VDVVRHEN 0xC2 +#define ST7789_VRHS 0xC3 +#define ST7789_VDVS 0xC4 +#define ST7789_VCMOFSET 0xC5 +#define ST7789_FRCTRL2 0xC6 +#define ST7789_CABCCTRL 0xC7 +#define ST7789_REGSEL1 0xC8 +#define ST7789_REGSEL2 0xCA +#define ST7789_PWMFRSEL 0xCC +#define ST7789_PWCTRL1 0xD0 +#define ST7789_VAPVANEN 0xD2 +#define ST7789_PVGAMCTRL 0xE0 +#define ST7789_NVGAMCTRL 0xE1 + +#define ST7789_MADCTL_MY 0x80 +#define ST7789_MADCTL_MX 0x40 +#define ST7789_MADCTL_MV 0x20 +#define ST7789_MADCTL_ML 0x10 +#define ST7789_MADCTL_RGB 0x00 + +#define ST7789_RDID1 0xDA +#define ST7789_RDID2 0xDB +#define ST7789_RDID3 0xDC +#define ST7789_RDID4 0xDD + +#define DISPLAY_MADCTL (ST7789_MADCTL_RGB) +#define DISPLAY_VSCSAD 0 + +// The init_sequence is bitpacked to minimize the ram impact. Every command begins with a +// command byte followed by a byte to determine the parameter count and delay. When the top bit +// of the second byte is 1 (0x80), a delay will occur after the command parameters are sent. +// The remaining 7 bits are the parameter count excluding any delay byte. The bytes following +// are the parameters. When the delay bit is set, a single byte after the parameters specifies +// the delay duration in milliseconds. The value 0xff will lead to an extra long 500 ms delay +// instead of 255 ms.uint8_t display_init_sequence[] = { +// display init sequence according to LilyGO example app + +uint8_t display_init_sequence[] = { + // From Lilygo example + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 120, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, DISPLAY_MADCTL, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x21, 0 | DELAY, 10, // _INVON + 0x29, 0 | DELAY, 120 +}; + + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO6); + common_hal_never_reset_pin(&pin_GPIO7); + #endif /* DEBUG */ + + // Display + + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO12, // CLK + &pin_GPIO11, // MOSI + NULL // MISO not connected + ); + + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO14, // DC + &pin_GPIO10, // CS + &pin_GPIO9, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + // workaround as board_init() is called before reset_port() in main.c + pwmout_reset(); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 80, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // There is no backlight pin, defined for now. + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false // SH1107_addressing + ); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { + common_hal_displayio_release_displays(); +} diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h new file mode 100644 index 0000000000..6a18f996bb --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "MORPHEANS MorphESP-240" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO6) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO13) diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk new file mode 100644 index 0000000000..aee744ca1a --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303a +USB_PID = 0x80B7 +USB_PRODUCT = "MORPHESP-240" +USB_MANUFACTURER = "MORPHEANS" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_MODULE = wroom diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/pins.c b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c new file mode 100644 index 0000000000..f311daeaa2 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c @@ -0,0 +1,58 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + // Serial UART on breakout board + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO18) }, + + // I2C on breakout board. + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + + // WS2812B RGB LED + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + + // SPI on breakout board + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, + + // 1.3" 240x240 LCD ST7789 + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig b/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig new file mode 100644 index 0000000000..36ada0b0c7 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig @@ -0,0 +1,6 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="MORPHESP-240" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of LWIP \ No newline at end of file diff --git a/ports/esp32s2/boards/odt_pixelwing_esp32_s2/board.c b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/board.c new file mode 100644 index 0000000000..5abd1ce1b3 --- /dev/null +++ b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/board.c @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { +} diff --git a/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.h b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.h new file mode 100644 index 0000000000..46d1084d19 --- /dev/null +++ b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Oak Dev Tech PixelWing ESP32S2" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO45) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) diff --git a/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk new file mode 100644 index 0000000000..c3880b6ae9 --- /dev/null +++ b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x1209 +USB_PID = 0x4DF0 +USB_PRODUCT = "Pixelwing ESP32S2" +USB_MANUFACTURER = "Oak Dev Tech" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE=dio +CIRCUITPY_ESP_FLASH_FREQ=40m +CIRCUITPY_ESP_FLASH_SIZE=4MB + +CIRCUITPY_MODULE=wrover diff --git a/ports/esp32s2/boards/odt_pixelwing_esp32_s2/pins.c b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/pins.c new file mode 100644 index 0000000000..9396b536f3 --- /dev/null +++ b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/pins.c @@ -0,0 +1,15 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_GPIO33) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_GPIO34) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/odt_pixelwing_esp32_s2/sdkconfig b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/sdkconfig new file mode 100644 index 0000000000..f67a257854 --- /dev/null +++ b/ports/esp32s2/boards/odt_pixelwing_esp32_s2/sdkconfig @@ -0,0 +1,39 @@ +CONFIG_ESP32S2_SPIRAM_SUPPORT=y + +# +# SPI RAM config +# +# CONFIG_SPIRAM_TYPE_AUTO is not set +CONFIG_SPIRAM_TYPE_ESPPSRAM16=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_SIZE=2097152 + +# +# PSRAM clock and cs IO for ESP32S2 +# +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# end of PSRAM clock and cs IO for ESP32S2 + +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +# CONFIG_SPIRAM_SPEED_80M is not set +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set +CONFIG_SPIRAM_USE_MEMMAP=y +# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="PixelWing-ESP32S2" +# end of LWIP diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 7a977b093c..77dc2ff3f2 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -62,6 +62,11 @@ void alarm_reset(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } +// This will be reset to false by full resets when bss is cleared. Otherwise, the +// reload is due to CircuitPython and the ESP wakeup cause will be stale. This +// can happen if USB is connected after a deep sleep. +STATIC bool soft_wakeup = false; + STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) { // First check if the modules remember what last woke up if (alarm_pin_pinalarm_woke_this_cycle()) { @@ -75,7 +80,11 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) { } // If waking from true deep sleep, modules will have lost their state, // so check the deep wakeup cause manually - return esp_sleep_get_wakeup_cause(); + if (!soft_wakeup) { + soft_wakeup = true; + return esp_sleep_get_wakeup_cause(); + } + return ESP_SLEEP_WAKEUP_UNDEFINED; } bool common_hal_alarm_woken_from_sleep(void) { diff --git a/ports/esp32s2/common-hal/canio/Listener.c b/ports/esp32s2/common-hal/canio/Listener.c index 5e968f2393..8100261743 100644 --- a/ports/esp32s2/common-hal/canio/Listener.c +++ b/ports/esp32s2/common-hal/canio/Listener.c @@ -151,6 +151,11 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { if (supervisor_ticks_ms64() > deadline) { return NULL; } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return NULL; + } } while (!common_hal_canio_listener_in_waiting(self)); } diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 9f48e62568..85b3b81910 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -31,7 +31,7 @@ CIRCUITPY_ROTARYIO = 1 CIRCUITPY_NVM = 1 CIRCUITPY_PS2IO ?= 1 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 -CIRCUITPY_WIFI = 1 +CIRCUITPY_WIFI ?= 1 CIRCUITPY_WATCHDOG ?= 1 CIRCUITPY_ESPIDF = 1 diff --git a/ports/esp32s2/supervisor/usb.c b/ports/esp32s2/supervisor/usb.c index 05e0746b00..0aa379b166 100644 --- a/ports/esp32s2/supervisor/usb.c +++ b/ports/esp32s2/supervisor/usb.c @@ -28,6 +28,7 @@ #include "py/runtime.h" #include "supervisor/usb.h" #include "supervisor/esp_port.h" +#include "supervisor/port.h" #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" @@ -109,6 +110,7 @@ void init_usb_hardware(void) { usb_device_stack, &usb_device_taskdef); } + /** * Callback invoked when received an "wanted" char. * @param itf Interface index (for multiple cdc interfaces) @@ -116,13 +118,13 @@ void init_usb_hardware(void) { */ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; // not used + // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. + // So, we must notify the other task when a CTRL-C is received. + port_wake_main_task(); // Workaround for using lib/utils/interrupt_char.c // Compare mp_interrupt_char with wanted_char and ignore if not matched if (mp_interrupt_char == wanted_char) { tud_cdc_read_flush(); // flush read fifo mp_sched_keyboard_interrupt(); - // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. - // So, we must notify the other task when a CTRL-C is received. - xTaskNotifyGive(circuitpython_task); } } diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index ce74f5d203..66cf4e2008 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -120,7 +120,7 @@ CFLAGS += \ # TODO: check this CFLAGS += -D__START=main -LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs +LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-z,max-page-size=0x1000 -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs LIBS := -lgcc -lc LDFLAGS += -mthumb -mcpu=cortex-m4 @@ -191,7 +191,7 @@ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(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/. +# because a few modules have files both in common-hal/ and shared-module/. # Doing a $(sort ...) removes duplicates as part of sorting. SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) diff --git a/ports/esp32s2/common-hal/busio/OneWire.h b/ports/nrf/boards/bluemicro840/board.c similarity index 80% rename from ports/esp32s2/common-hal/busio/OneWire.h rename to ports/nrf/boards/bluemicro840/board.c index bb6a014190..688cfb4ded 100644 --- a/ports/esp32s2/common-hal/busio/OneWire.h +++ b/ports/nrf/boards/bluemicro840/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Scott Shawcroft + * 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 @@ -24,10 +24,15 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_BUSIO_ONEWIRE_H +#include "supervisor/board.h" -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +void board_init(void) { +} -#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_BUSIO_ONEWIRE_H +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/bluemicro840/mpconfigboard.h b/ports/nrf/boards/bluemicro840/mpconfigboard.h new file mode 100644 index 0000000000..99a1e0bfbe --- /dev/null +++ b/ports/nrf/boards/bluemicro840/mpconfigboard.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2021 Pierre Constantineau + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "BlueMicro840" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define BOARD_HAS_CRYSTAL 1 + +#define MICROPY_HW_LED_STATUS (&pin_P1_04) // RED + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_17) // 0.17 - same position as Pro Micro +#define DEFAULT_I2C_BUS_SDA (&pin_P0_15) // 0.15 - same position as Pro Micro + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_24) // 0.24 - same position as Pro Micro +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_10) // 0.10 - same position as Pro Micro +#define DEFAULT_SPI_BUS_MISO (&pin_P0_09) // 0.09 - same position as Pro Micro + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) // 0.08 - same position as Pro Micro +#define DEFAULT_UART_BUS_TX (&pin_P0_06) // 0.06 - same position as Pro Micro diff --git a/ports/nrf/boards/bluemicro840/mpconfigboard.mk b/ports/nrf/boards/bluemicro840/mpconfigboard.mk new file mode 100644 index 0000000000..16d36704a3 --- /dev/null +++ b/ports/nrf/boards/bluemicro840/mpconfigboard.mk @@ -0,0 +1,8 @@ +USB_VID = 0x1D50 +USB_PID = 0x6161 +USB_PRODUCT = "BlueMicro840" +USB_MANUFACTURER = "nrf52.jpconstantineau.com" + +MCU_CHIP = nrf52840 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c new file mode 100644 index 0000000000..e33aff2bfa --- /dev/null +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -0,0 +1,76 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { 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_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/particle_argon/mpconfigboard.h b/ports/nrf/boards/particle_argon/mpconfigboard.h index a4952fc797..a858a20b05 100644 --- a/ports/nrf/boards/particle_argon/mpconfigboard.h +++ b/ports/nrf/boards/particle_argon/mpconfigboard.h @@ -30,11 +30,9 @@ #define MICROPY_HW_BOARD_NAME "Particle Argon" #define MICROPY_HW_MCU_NAME "nRF52840" -#define MICROPY_HW_LED_STATUS (&pin_P1_12) - -#define MICROPY_HW_RGB_LED_RED (&pin_P0_13) -#define MICROPY_HW_RGB_LED_GREEN (&pin_P0_14) -#define MICROPY_HW_RGB_LED_BLUE (&pin_P0_15) +#define CIRCUITPY_RGB_STATUS_R (&pin_P0_13) +#define CIRCUITPY_RGB_STATUS_G (&pin_P0_14) +#define CIRCUITPY_RGB_STATUS_B (&pin_P0_15) #if QSPI_FLASH_FILESYSTEM #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) diff --git a/ports/nrf/boards/particle_boron/mpconfigboard.h b/ports/nrf/boards/particle_boron/mpconfigboard.h index bab1b3d5cd..fd000d7376 100644 --- a/ports/nrf/boards/particle_boron/mpconfigboard.h +++ b/ports/nrf/boards/particle_boron/mpconfigboard.h @@ -30,11 +30,9 @@ #define MICROPY_HW_BOARD_NAME "Particle Boron" #define MICROPY_HW_MCU_NAME "nRF52840" -#define MICROPY_HW_LED_STATUS (&pin_P1_12) - -#define MICROPY_HW_RGB_LED_RED (&pin_P0_13) -#define MICROPY_HW_RGB_LED_GREEN (&pin_P0_14) -#define MICROPY_HW_RGB_LED_BLUE (&pin_P0_15) +#define CIRCUITPY_RGB_STATUS_R (&pin_P0_13) +#define CIRCUITPY_RGB_STATUS_G (&pin_P0_14) +#define CIRCUITPY_RGB_STATUS_B (&pin_P0_15) #if QSPI_FLASH_FILESYSTEM #define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 20) diff --git a/ports/nrf/boards/raytac_mdbt50q-db-40/mpconfigboard.h b/ports/nrf/boards/raytac_mdbt50q-db-40/mpconfigboard.h index 93fdce3a0e..28bfbd1703 100644 --- a/ports/nrf/boards/raytac_mdbt50q-db-40/mpconfigboard.h +++ b/ports/nrf/boards/raytac_mdbt50q-db-40/mpconfigboard.h @@ -28,3 +28,4 @@ #define MICROPY_HW_MCU_NAME "nRF52840" #define MICROPY_HW_LED_STATUS (&pin_P0_13) +#define MICROPY_HW_LED_STATUS_INVERTED (1) diff --git a/ports/nrf/boards/raytac_mdbt50q-db-40/pins.c b/ports/nrf/boards/raytac_mdbt50q-db-40/pins.c index 426498cc20..10f42f9027 100644 --- a/ports/nrf/boards/raytac_mdbt50q-db-40/pins.c +++ b/ports/nrf/boards/raytac_mdbt50q-db-40/pins.c @@ -66,6 +66,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_P0_07) }, { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_P0_05) }, + // Note that these are inverted; you must pull them low to turn on the LEDs. { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_P0_14) }, { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_P0_15) }, diff --git a/ports/mimxrt10xx/common-hal/busio/OneWire.h b/ports/nrf/boards/raytac_mdbt50q-rx/board.c similarity index 80% rename from ports/mimxrt10xx/common-hal/busio/OneWire.h rename to ports/nrf/boards/raytac_mdbt50q-rx/board.c index bb4bc016a4..688cfb4ded 100644 --- a/ports/mimxrt10xx/common-hal/busio/OneWire.h +++ b/ports/nrf/boards/raytac_mdbt50q-rx/board.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Scott Shawcroft + * 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 @@ -24,10 +24,15 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_BUSIO_ONEWIRE_H +#include "supervisor/board.h" -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +void board_init(void) { +} -#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_BUSIO_ONEWIRE_H +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.h b/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.h new file mode 100644 index 0000000000..92629a9e47 --- /dev/null +++ b/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * + * 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. + */ + +#define MICROPY_HW_BOARD_NAME "MDBT50Q-RX Dongle" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define MICROPY_HW_LED_STATUS (&pin_P1_13) +#define MICROPY_HW_LED_STATUS_INVERTED (1) diff --git a/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.mk b/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.mk new file mode 100644 index 0000000000..08c7266d36 --- /dev/null +++ b/ports/nrf/boards/raytac_mdbt50q-rx/mpconfigboard.mk @@ -0,0 +1,8 @@ +USB_VID = 0x239A +USB_PID = 0x810C +USB_PRODUCT = "MDBT50Q-RX Dongle" +USB_MANUFACTURER = "Raytac Corporation" + +MCU_CHIP = nrf52840 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/raytac_mdbt50q-rx/pins.c b/ports/nrf/boards/raytac_mdbt50q-rx/pins.c new file mode 100644 index 0000000000..db5e7f769d --- /dev/null +++ b/ports/nrf/boards/raytac_mdbt50q-rx/pins.c @@ -0,0 +1,11 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P0_15) }, + + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_INVERTED_LED), MP_ROM_PTR(&pin_P1_13) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md index 094102c277..5c41fdb7cf 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md @@ -10,56 +10,64 @@ We've also routed two I2C buses, 2 SPI buses, eleven GPIO, dedicated CircuitPython pin definitions, while simialr to other boards represent a slight departure from just the typical `A` and `D` pin definitions. The majority of general pins are labled as `G` (or alternatively, `BUS`,) as the MicroMod system they build on uses those names to specify pins that may not be specficially analog or digital. -This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map. This pin map will use the label either on the [SparkFun MicroMod ATP Carrier Board](https://www.sparkfun.com/products/16885), or the pin name on the [graphical datasheet](https://cdn.sparkfun.com/assets/learn_tutorials/1/4/0/1/MicroMod_nRF52840_v1.0_Graphical_Datasheet.pdf). Some of the aditional aliases are just names to make naming consistent (e.g.: RTS/CTS), but they also can refer to additional functionality a pin may have (e.g.: NFC pins) +This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map: MicroMod Pin # | ATP Pin Label | Pin Definition | Additional Definitons | Pin/Port Reference | Notes :--------------|:--------------|:--------------|:-----------------------|:-------------------|:------ 8 | G11 | | | (Not Connected) | 10 | D0 | D0 | | P0_27 | -11 | BOOT | BOOT | BUTTON1 | P0_07 | -12 | SDA | SDA | | P0_08 | -13 | RTS1 | RTS | RTS1 | P1_02 | -14 | SCL | SCL | | P0_11 | -15 | CTS1 | CTS | CTS1 | P1_09 | -16 | /I2C INT | I2C_INT | P0_15 | -17 | TX | TX | TX1 | P1_03 | -18 | D1 | D1 | CAM_TRIG | P1_08 | -19 | RX | RX | RX1 | P1_10 | -20 | RX2 | RX2 | | P1_05 | -22 | TX2 | TX2 | | P1_07 | -32 | PWM0 | PWM0 | P0_06 | -34 | A0 | A0 | ADC0 | P0_04 | Attached to AIN2 -38 | A1 | A1 | ADC1 | P0_05 | Attached to AIN3 +11 | BOOT | BOOT | | P0_07 | +12 | SDA | I2C_SDA | SDA | P0_08 | +13 | RTS1 | UART_RTS1 | | P1_02 | +14 | SCL | I2C_SCL | SCL | P0_11 | +15 | CTS1 | UART_CTS1 | | P1_09 | +16 | /I2C INT | I2C_INT | |P0_15| +17 | TX | UART_TX1 | TX | P1_03 | +18 | D1 | D1 | | P1_08 | +19 | RX | UART_RX1 | RX | P1_10 | +20 | RX2 | UART_RX2 | | P1_05 | +22 | TX2 | UART_TX2 | | P1_07 | +32 | PWM0 | PWM0 | |P0_06| +34 | A0 | A0 | | P0_04 | Attached to AIN2 +38 | A1 | A1 | | P0_05 | Attached to AIN3 40 | G0 | G0 | BUS0 | P0_29 | Attached to AIN5 42 | G1 | G1 | BUS1 | P0_03 | Attached to AIN1 44 | G2 | G2 | BUS2 | P1_13 | 46 | G3 | G3 | BUS3 | P1_12 | -47 | PWM1 | PWM1 | P0_16 | +47 | PWM1 | PWM1 | |P0_16| 48 | G4 | G4 | BUS4 | P1_11 | -49 | BATT_VIN | BATT_VIN3 | | P0_30 | Attached to AIN6, will be battery voltage / 3. | +49 | BATT_VIN | BATT_VIN3 | | P0_30 | Attached to AIN6, will be battery voltage / 3. 50 | PDM_CLK | PDM_CLK | | P0_25 | -51 | SDA1 | SDA1 | | P1_01 | +51 | SDA1 | I2C_SDA1 | | P1_01 | 52 | PDM_DATA | PDM_DATA | | P0_26 | -53 | SCL1 | SCL1 | | P0_24 | -55 | /CS | CS | | P0_20 | -57 | SCK | SCK | | P0_28 | Attached to AIN4 -59 | COPI | COPI | MOSI | P0_31 | Attached to AIN7 -61 | CIPO | CIPO | MISO | P0_02 | -63 | G10 | G10 | NFC2, ADC_DP, CAM_VSYNC | P0_10 | Attached to NFC2 -65 | G9 | G9 | NFC1, ADC_DM, CAM_HSYNC | P0_09 | Attached to NFC1 +53 | SCL1 | I2C_SCL1 | | P0_24 | +55 | /CS | SPI_CS | | P0_20 | +57 | SCK | SPI_SCK | LED_CLK | P0_28 | Attached to AIN4 +59 | COPI | SPI_COPI | SPI_MOSI, LED_DAT | P0_31 | Attached to AIN7 +60 | SCK1 | SDIO_SCK | SPI_SCK1 | | +61 | CIPO | SPI_CIPO | SPI_MISO | P0_02 | +62 | COPI1 | SDIO_CMD | SPI_COPI1 | | +63 | G10 | G10 | | P0_10 | Attached to NFC2 +64 | CIPO1 | SDIO_DATA0 | SPI_CIPO1 | | +65 | G9 | G9 | | P0_09 | Attached to NFC1 +66 | DAT1 | SDIO_DATA1 | | | 67 | G8 | G8 | | P1_14 | +68 | DAT2 | SDIO_DATA2 | | | 69 | G7 | G7 | BUS7 | P1_04 | +70 | CS1 | SDIO_DATA3 | SPI_CS1 | | 71 | G6 | G6 | BUS6 | P1_06 | 73 | G5 | G5 | BUS5 | P0_15 | ## Peripheral Naming -CircuitPython attempts to stay in line with the naming of the serial peripheral naming in the MicroMod system. The bare UART pins are also named 1. The UART 2 pins are named 2. However, the I2C names on MicroMod are and 1. Perhaps this will change in the future, but as of [Interface v1](https://cdn.sparkfun.com/assets/learn_tutorials/1/2/0/6/SparkFun_MicroMod_Interface_v1.0_-_Pin_Descriptions.pdf), it may lead to some confusion. +The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. The 0th peripheral is the default and the "0" is omitted from the peripheral name. For example, the first I2C peripheral is named `I2C` (instead of `I2C0`) and the second I2C peripheral is named `I2C1`. Note: MicroMod `UART` is not present in the edge connector pinout because the primary debug serial port (i.e.`UART0`) is exposed as a virtual serial port over USB. As a result, the first UART peripheral in the edge connector pinout is `UART1` and the second UART peripheral is `UART2`. + +For more details, see https://www.sparkfun.com/micromod#tech-specs. ## Bootloader Notes -The MicroMod nRF52840 Processor needs to have the [Adafruit nRF52 UF2 bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader/pull/194) flashed on it. [[TODO: LINK TO BUILD]] +The MicroMod nRF52840 Processor needs to have the [Adafruit nRF52 UF2 bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/latest) flashed on it. ## Hardware Reference diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h index c53fc45d22..fec1d5ae02 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h @@ -27,9 +27,12 @@ #include "nrfx/hal/nrf_gpio.h" -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod nRF52840" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod nRF52840 Processor" #define MICROPY_HW_MCU_NAME "nRF52840" +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_P0_13) + #define DEFAULT_I2C_BUS_SCL (&pin_P0_11) #define DEFAULT_I2C_BUS_SDA (&pin_P0_08) diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk index 21ca20825a..83d51ecc6d 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk @@ -1,6 +1,6 @@ USB_VID = 0x1B4F USB_PID = 0x0021 -USB_PRODUCT = "SFE_nRF52840_MicroMod" +USB_PRODUCT = "SparkFun MicroMod nRF52840 Processor" USB_MANUFACTURER = "SparkFun Electronics" MCU_CHIP = nrf52840 diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c b/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c index 65700f24e4..11ca39f28d 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c @@ -1,113 +1,221 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * 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/board/__init__.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - // D pins (D0-D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_27) }, // 0.27 - D0 - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P1_08) }, // 1.08 - D1 | CAM_TRIG - { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_P1_08) }, // CAM_TRIG alias + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A pins (A0-A1) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, // 0.04 - A0 | ADC0 (AIN2) - { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_P0_04) }, // ADC0 alias - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, // 0.05 - A1 | ADC1 (AIN3) - { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_P0_05) }, // ADC1 alias + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_13) }, // MicroMod LED (P0.13) - // G pins (G0-G11, G11 NC) - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_P0_29) }, // 0.29 - G0 | GPIO0 | BUS0 (AIN5) - { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_P0_29) }, // BUS0 alias - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_P0_03) }, // 0.03 - G1 | GPIO1 | BUS1 (AIN1) - { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_P0_03) }, // BUS1 alias - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_P1_13) }, // 1.13 - G2 | GPIO2 | BUS2 - { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_P1_13) }, // BUS2 alias - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_P1_12) }, // 1.12 - G3 | GPIO3 | BUS3 - { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_P1_12) }, // BUS3 alias - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_P1_11) }, // 1.11 - G4 | GPIO4 | BUS4 - { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_P1_11) }, // BUS4 alias - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_P0_17) }, // 0.17 - G5 | GPIO5 | BUS5 - { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_P0_17) }, // BUS5 alias - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_P1_06) }, // 1.06 - G6 | GPIO6 | BUS6 - { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_P1_06) }, // BUS6 alias - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_P1_04) }, // 1.04 - G7 | GPIO7 | BUS7 - { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_P1_04) }, // BUS7 alias - { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_P1_14) }, // 1.14 - G8 | GPIO8 - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_P0_09) }, // 0.09 - G9 | GPIO9/NFC1 | ADC_D- | CAM_HSYNC (NFC1) - { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, // NFC1 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_P0_09) }, // ADC_DM alias - { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_P0_09) }, // CAM_HSYNC alias - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_P0_10) }, // 0.10 - G10 | GPIO10/NFC2 | ADC_D+ | CAM_VSYNC (NFC2) - { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, // NFC2 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_P0_10) }, // ADC_DP alias - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_P0_10) }, // CAM_VSYNC alias - // NC - G11 + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (MDBT50Q-P1M has a dedicated HW VBUS pin) - // PWM pins (PWM0-PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_P0_06) }, // 0.06 - PWM0 - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_P0_16) }, // 0.16 - PWM1 + // MicroMod +3.3V enable pin + { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR(&pin_P1_15) }, // MicroMod 3.3V_EN (P1.15) - // PDM - { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_P0_25) }, // 0.25 - PDM_CLK | AUD_BCLK - { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_P0_26) }, // 0.26 - PDM_DATA | AUD_LRCLK + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_P0_30) }, // MicroMod BATT_VIN/3 (P0.30) - // Battery Voltage Monitor - { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_P0_30) }, // 0.30 - BATT_VIN/3 (AIN6) + // MicroMod reset pin + { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P0_18) }, // MicroMod RESET# (P0.18) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // 0.08 - SDA - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // 0.11 - SCL (TRACEDATA2) + // MicroMod boot pin + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_P0_07) }, // MicroMod BOOT (P0.07) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_P0_15) }, // 0.15 - I2C_INT + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR() }, // MicroMod USB_D- (MDBT50Q-P1M has a dedicated HW D- pin) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR() }, // MicroMod USB_D+ (MDBT50Q-P1M has a dedicated HW D+ pin) - { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_P1_01) }, // 1.01 - SDA1 - { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_P0_24) }, // 0.24 - SCL1 + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (not supported) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (not supported) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_P0_02) }, // 0.02 - CIPO | SPI_CIPO - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_02) }, // MISO alias - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_P0_31) }, // 0.31 - COPI | SPI_COPI (AIN7) - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_31) }, // MOSI alias - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_28) }, // 0.28 - SCK | SPI_SCK (AIN4) - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_20) }, // 0.20 - /CS | SPI_/CS + // MicroMod CAN pins + // { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR() }, // MicroMod CAN_RX (not supported) + // { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR() }, // MicroMod CAN_TX (not supported) - // QSPI, used by flash on this board, but is broken out - // on the MicroMod connector, to to the SDIO pins. - { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_P0_19) }, // 0.00 - SDIO SCK | Used as: QSPI flash SCK - { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_P0_19) }, // SPI_SCK1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_P0_14) }, // 0.00 - SDIO CMD | Used as: QSPI flash D0 (or SDI) - { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_P0_14) }, // SPI_COPI1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_P0_21) },// 0.00 - SDIO DATA0 | Used as: QSPI flash D1 (or SDO) - { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_P0_21) }, // SPI_CIPO1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_P0_22) },// 0.00 - SDIO DATA1 | Unused for flash. - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_P0_23) },// 0.00 - SDIO DATA2 | Used as: QSPI flash D2 - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_P1_00) },// 0.00 - SDIO DATA3 | Use das: QSPI flash D3 (or /HOLD) - { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_P1_00) }, // SPI_CS1 alias + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // Reset Pin - { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P1_14) }, // 0.18 - /RESET (NRESET) + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_P1_03) }, // MicroMod UART_TX1 | CircuitPython TX (P1.03) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_P1_10) }, // MicroMod UART_RX1 | CircuitPython RX (P1.10) + { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR(&pin_P1_02) }, // MicroMod RTS1 (P1.02) + { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR(&pin_P1_09) }, // MicroMod CTS1 (P1.09) - // LED - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_13) }, // 0.13 - LED_BUILTIN | STAT | Blue LED + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_03) }, // CircuitPython TX | MicroMod UART_TX1 (P1.03) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_10) }, // CircuitPython RX | MicroMod UART_RX1 (P1.10) - // Button - { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_07) }, // 0.07 - /BOOT [Active Low] (TRACECLK) - Is button on carriers. - { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_P0_07) }, // BOOT alias + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_P1_07) }, // MicroMod UART_TX2 (P1.07) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_P1_05) }, // MicroMod UART_RX2 (P1.05) - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_10) }, // 1.10 - UART RX | RX1 - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_P1_10) }, // RX1 alias - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_03) }, // 1.03 - UART TX | TX1 - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_P1_03) }, // TX1 alias - { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_P1_09) }, // 1.09 - UART CTS | CTS1 (TRACEDATA3) - { MP_ROM_QSTR(MP_QSTR_CTS1), MP_ROM_PTR(&pin_P1_09) }, // CTS1 alias - { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_P1_02) }, // 1.02 - UART RTS | RTS1 - { MP_ROM_QSTR(MP_QSTR_RTS1), MP_ROM_PTR(&pin_P1_02) }, // RTS1 alias + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_P0_08) }, // MicroMod I2C_SDA (P0.08) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_P0_11) }, // MicroMod I2C_SCL (P0.11) - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_P1_05) }, // 1.05 - UART RX | RX2 - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_P1_07) }, // 1.07 - UART TX | TX2 + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // CircuitPython SDA | MicroMod I2C_SDA (P0.08) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // CircuitPython SCL | MicroMod I2C_SCL (P0.11) - // Board Objects - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_P0_15) }, // MicroMod I2C_INT (P0.15) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_P1_01) }, // MicroMod I2C_SDA1 (P1.01) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_P0_24) }, // MicroMod I2C_SCL1 (P0.24) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_P0_02) }, // MicroMod SPI_CIPO | CircuitPython CIPO (P0.02) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_P0_02) }, // MicroMod SPI_MISO | CircuitPython MISO (P0.02) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_P0_31) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (P0.31) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_P0_31) }, // MicroMod SPI_MOSI | CircuitPython MOSI (P0.31) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_P0_28) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (P0.28) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_P0_20) }, // MicroMod SPI_CS | CircuitPython CS (P0.20) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_P0_02) }, // CircuitPython CIPO | MicroMod SPI_CIPO (P0.02) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_02) }, // CircuitPython MISO | MicroMod SPI_MISO (P0.02) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_P0_31) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (P0.31) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_31) }, // CircuitPython MOSI | MicroMod SPI_MOSI (P0.31) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_28) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (P0.28) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_20) }, // CircuitPython CS | MicroMod SPI_CS (P0.20) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_P0_31) }, // MicroMod LED_DAT | SPI_COPI (P0.31) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_P0_28) }, // MicroMod LED_CLK | SPI_SCK (P0.28) + + // MicroMod SDIO pins + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_P0_19) }, // MicroMod SDIO_SCK | SPI_SCK1 (P0.19) + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SDIO_CMD | SPI_COPI1 (P0.14) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_P0_22) }, // MicroMod SDIO_DATA1 (P0.22) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_P0_23) }, // MicroMod SDIO_DATA2 (P0.23) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_P1_00) }, // MicroMod SDIO_DATA3 | SPI_CS1 (P1.00) + + // MicroMod SPI1 pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SPI_MISO1 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SPI_COPI1 | SDIO_CMD (P0.14) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SPI_MOSI1 (P0.14) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_P0_19) }, // MicroMod SPI_SCK1 | SDIO_SCK (P0.19) + { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_P1_00) }, // MicroMod SPI_CS1 | SDIO_DATA3 (P1.00) + + // MicroMod audio pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR() }, // MicroMod AUD_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR() }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR() }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_P0_26) },// MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (P0.25) + + // MicroMod I2S pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR() }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR() }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_P0_26) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (P0.25) + + // MicroMod PCM pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR() }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR() }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_P0_26) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (P0.25) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_P0_26) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (P0.26) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (P0.25) + + // MicroMod SWD pins + // { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR() }, // MicroMod SWDIO (MDBT50Q-P1M has a dedicated HW SWDIO pin) + // { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR() }, // MicroMod SWDCK (MDBT50Q-P1M has a dedicated HW SWDCLK pin) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not supported) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_05) }, // MicroMod A0 (P0.05) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, // MicroMod A1 (P0.04) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_P0_06) }, // MicroMod PWM0 (P0.06) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_P0_16) }, // MicroMod PWM1 (P0.16) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_27) }, // MicroMod D0 (P0.27) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P1_08) }, // MicroMod D1 | CAM_TRIG (P1.08) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_P0_29) }, // MicroMod G0 | BUS0 (P0.29) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_P0_03) }, // MicroMod G1 | BUS1 (P0.03) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_P1_13) }, // MicroMod G2 | BUS2 (P1.13) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_P1_12) }, // MicroMod G3 | BUS3 (P1.12) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_P1_11) }, // MicroMod G4 | BUS4 (P1.11) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_P0_17) }, // MicroMod G5 | BUS5 (P0.17) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_P1_06) }, // MicroMod G6 | BUS6 (P1.06) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_P1_04) }, // MicroMod G7 | BUS7 (P1.04) + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_P1_14) }, // MicroMod G8 (P1.14) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_P0_09) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (P0.09) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_P0_10) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (P0.10) + // { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR() }, // MicroMod G11 | SWO (not connected) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_P0_29) }, // MicroMod BUS0 | G0 (P0.29) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_P0_03) }, // MicroMod BUS1 | G1 (P0.03) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_P1_13) }, // MicroMod BUS2 | G2 (P1.13) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_P1_12) }, // MicroMod BUS3 | G3 (P1.12) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_P1_11) }, // MicroMod BUS4 | G4 (P1.11) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_P0_17) }, // MicroMod BUS5 | G5 (P0.17) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_P1_06) }, // MicroMod BUS6 | G6 (P1.06) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_P1_04) }, // MicroMod BUS7 | G7 (P1.04) + + // MicroMod differential ADC input pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_P0_09) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (P0.09) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_P0_10) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (P0.10) + + // MicroMod camera pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR() }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR() }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_P1_08) }, // MicroMod CAM_TRIG | D1 (P1.08) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_P0_09) },// MicroMod CAM_HSYNC | ADC_D- | G9 (P0.09) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_P0_10) },// MicroMod CAM_VSYNC | ADC_D+ | G10 (P0.10) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; - MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 9f5f46f656..f4302b839d 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -952,8 +952,11 @@ bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) { } void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) { - gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t)); - gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / sizeof(size_t)); + // We divide by size_t so that we can scan each 32-bit aligned value to see + // if it is a pointer. This allows us to change the structs without worrying + // about collecting new pointers. + gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / (sizeof(size_t))); + gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / (sizeof(size_t))); } void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 8accc88764..117fa1168f 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -137,6 +137,8 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) { // Set up light sleep or deep sleep alarms. STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); @@ -156,10 +158,6 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { if (timediff_ms != -1) { have_timeout = true; - #if 0 - int64_t now = common_hal_time_monotonic_ms(); - dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); - #endif if (timediff_ms < 0) { timediff_ms = 0; } @@ -175,34 +173,17 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { start_tick = port_get_raw_ticks(NULL); end_tick = start_tick + tickdiff; } - #if 0 - dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); - #endif int64_t remaining; - sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; - sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; - - #ifdef NRF_DEBUG_PRINT - int ct = 40; - char reason = '?'; -#define WAKEUP_REASON(x) reason = (x) - #else -#define WAKEUP_REASON(x) - #endif - while (1) { if (mp_hal_is_interrupted()) { - WAKEUP_REASON('I'); break; } if (serial_connected() && serial_bytes_available()) { - WAKEUP_REASON('S'); break; } RUN_BACKGROUND_TASKS; if (common_hal_alarm_woken_from_sleep()) { - WAKEUP_REASON('W'); break; } if (have_timeout) { @@ -210,51 +191,28 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { // We break a bit early so we don't risk setting the alarm before the time when we call // sleep. if (remaining < 1) { - WAKEUP_REASON('t'); break; } port_interrupt_after_ticks(remaining); } // Idle until an interrupt happens. port_idle_until_interrupt(); - #ifdef NRF_DEBUG_PRINT - if (ct > 0) { - mp_printf(&mp_plat_print, "_"); - --ct; - } - #endif if (have_timeout) { remaining = end_tick - port_get_raw_ticks(NULL); if (remaining <= 0) { sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; - WAKEUP_REASON('T'); break; } } } - #ifdef NRF_DEBUG_PRINT - mp_printf(&mp_plat_print, "%c\r\n", reason); - #endif #if defined(MICROPY_QSPI_CS) qspi_flash_exit_sleep(); #endif - - #ifdef NRF_DEBUG_PRINT - tickdiff = port_get_raw_ticks(NULL) - start_tick; - double sec; - if (prescaler == 0) { - sec = (double)tickdiff / 1024; - } else { - sec = (double)(tickdiff * prescaler) / 1024; - } - mp_printf(&mp_plat_print, "lapse %6.1f sec\r\n", sec); - #endif } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t wake_alarm = mp_const_none; - alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(false, n_alarms, alarms); #ifdef NRF_DEBUG_PRINT @@ -290,7 +248,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { - alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(true, n_alarms, alarms); } diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index 54d9a8921f..c5f3bfd705 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -70,10 +70,6 @@ int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void) { return wakeup_time_saved - common_hal_time_monotonic_ms(); } -void alarm_time_timealarm_clear_wakeup_time(void) { - wakeup_time_saved = 0; -} - void alarm_time_timealarm_reset(void) { port_disable_interrupt_after_ticks_ch(1); wakeup_time_saved = 0; diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index f606fe898f..55d1c967ac 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -269,18 +269,8 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size } bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { - uint8_t *next_chunk = data; - - while (len > 0) { - size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size); - const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_RX(next_chunk, chunk_size); - if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) { - return false; - } - next_chunk += chunk_size; - len -= chunk_size; - } - return true; + memset(data, write_value, len); + return common_hal_busio_spi_transfer(self, data, 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) { diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 840b723398..926c8de9fd 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -213,7 +213,7 @@ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(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/. +# because a few modules have files both in common-hal/ and shared-module/. # Doing a $(sort ...) removes duplicates as part of sorting. SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index 52b1c84b91..e9f62281cf 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -28,6 +28,7 @@ #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" +#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/background_callback.h" #include "py/mpstate.h" @@ -37,10 +38,8 @@ #if CIRCUITPY_AUDIOPWMIO || CIRCUITPY_AUDIOBUSIO -#define AUDIO_DMA_CHANNEL_COUNT NUM_DMA_CHANNELS - void audio_dma_reset(void) { - for (size_t channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { + for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) { if (MP_STATE_PORT(playing_audio)[channel] == NULL) { continue; } @@ -49,116 +48,152 @@ void audio_dma_reset(void) { } } -void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer_length, - uint8_t **output_buffer, uint32_t *output_buffer_length) { - if (dma->first_buffer_free) { - *output_buffer = dma->first_buffer; - } else { - *output_buffer = dma->second_buffer; - } + +STATIC void audio_dma_convert_samples( + audio_dma_t *dma, + uint8_t *input, uint32_t input_length, + uint8_t *available_output_buffer, uint32_t available_output_buffer_length, + uint8_t **output, uint32_t *output_length) { + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" + + // Check whether a conversion is necessary if (dma->signed_to_unsigned || dma->unsigned_to_signed || dma->sample_spacing > 1 || (dma->sample_resolution != dma->output_resolution)) { - *output_buffer_length = buffer_length / dma->sample_spacing; + + // Must convert. + // Write the conversion into the passed-in output buffer + *output = available_output_buffer; + *output_length = input_length / dma->sample_spacing; + + if (*output_length > available_output_buffer_length) { + mp_raise_RuntimeError(translate("Internal audio buffer too small")); + } + uint32_t out_i = 0; if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { + // reading bytes, writing 16-bit words, so output buffer will be bigger. + + *output_length = *output_length * 2; + if (*output_length > available_output_buffer_length) { + mp_raise_RuntimeError(translate("Internal audio buffer too small")); + } + size_t shift = dma->output_resolution - dma->sample_resolution; - for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t)((int8_t *)buffer)[i] + 0x80) << shift; + ((uint16_t *)*output)[out_i] = ((uint16_t)((int8_t *)input)[i] + 0x80) << shift; } else if (dma->unsigned_to_signed) { - ((int16_t *)*output_buffer)[out_i] = ((int16_t)((uint8_t *)buffer)[i] - 0x80) << shift; + ((int16_t *)*output)[out_i] = ((int16_t)((uint8_t *)input)[i] - 0x80) << shift; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t)((uint8_t *)buffer)[i]) << shift; + ((uint16_t *)*output)[out_i] = ((uint16_t)((uint8_t *)input)[i]) << shift; } out_i += 1; } } else if (dma->sample_resolution <= 8 && dma->output_resolution <= 8) { - for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint8_t *)*output_buffer)[out_i] = ((int8_t *)buffer)[i] + 0x80; + ((uint8_t *)*output)[out_i] = ((int8_t *)input)[i] + 0x80; } else if (dma->unsigned_to_signed) { - ((int8_t *)*output_buffer)[out_i] = ((uint8_t *)buffer)[i] - 0x80; + ((int8_t *)*output)[out_i] = ((uint8_t *)input)[i] - 0x80; } else { - ((uint8_t *)*output_buffer)[out_i] = ((uint8_t *)buffer)[i]; + ((uint8_t *)*output)[out_i] = ((uint8_t *)input)[i]; } out_i += 1; } } else if (dma->sample_resolution > 8 && dma->output_resolution > 8) { size_t shift = 16 - dma->output_resolution; - for (uint32_t i = 0; i < buffer_length / 2; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length / 2; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint16_t *)*output_buffer)[out_i] = ((int16_t *)buffer)[i] + 0x8000; + ((uint16_t *)*output)[out_i] = ((int16_t *)input)[i] + 0x8000; } else if (dma->unsigned_to_signed) { - ((int16_t *)*output_buffer)[out_i] = ((uint16_t *)buffer)[i] - 0x8000; + ((int16_t *)*output)[out_i] = ((uint16_t *)input)[i] - 0x8000; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t *)buffer)[i]; + ((uint16_t *)*output)[out_i] = ((uint16_t *)input)[i]; } if (dma->output_resolution < 16) { if (dma->output_signed) { - ((int16_t *)*output_buffer)[out_i] = ((int16_t *)*output_buffer)[out_i] >> shift; + ((int16_t *)*output)[out_i] = ((int16_t *)*output)[out_i] >> shift; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t *)*output_buffer)[out_i] >> shift; + ((uint16_t *)*output)[out_i] = ((uint16_t *)*output)[out_i] >> shift; } } out_i += 1; } + } else { + // (dma->sample_resolution > 8 && dma->output_resolution <= 8) + // Not currently used, but might be in the future. + mp_raise_RuntimeError(translate("Audio conversion not implemented")); } } else { - *output_buffer = buffer; - *output_buffer_length = buffer_length; + // No conversion necessary. Designate the input buffer as the output buffer. + *output = input; + *output_length = input_length; } #pragma GCC diagnostic pop - dma->first_buffer_free = !dma->first_buffer_free; } -void audio_dma_load_next_block(audio_dma_t *dma) { - uint8_t dma_channel = dma->channel[1]; - if (dma->first_channel_free) { - dma_channel = dma->channel[0]; - } - dma->first_channel_free = !dma->first_channel_free; +// channel_idx is 0 or 1. +STATIC void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { + size_t dma_channel = dma->channel[buffer_idx]; - uint8_t *output_buffer; - uint32_t output_buffer_length; audioio_get_buffer_result_t get_buffer_result; - uint8_t *buffer; - uint32_t buffer_length; + uint8_t *sample_buffer; + uint32_t sample_buffer_length; get_buffer_result = audiosample_get_buffer(dma->sample, - dma->single_channel_output, dma->audio_channel, &buffer, &buffer_length); + dma->single_channel_output, dma->audio_channel, &sample_buffer, &sample_buffer_length); if (get_buffer_result == GET_BUFFER_ERROR) { audio_dma_stop(dma); return; } - audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length); + // Convert the sample format resolution and signedness, as necessary. + // The input sample buffer is what was read from a file, Mixer, or a raw sample buffer. + // The output buffer is one of the DMA buffers (passed in), or if no conversion was done, + // the original sample buffer (to save copying). - // If we don't have an output buffer, save the pointer to first_buffer for use in the single - // buffer special case. - if (dma->first_buffer == NULL) { - dma->first_buffer = output_buffer; - } + // audio_dma_convert_samples() will write the converted samples into the given output + // buffer if necessary. If no conversion was needed, it will return the sample buffer + // as the output buffer. + uint8_t *output_buffer; + uint32_t output_buffer_length; + + audio_dma_convert_samples(dma, sample_buffer, sample_buffer_length, + dma->buffer[buffer_idx], dma->buffer_length[buffer_idx], + &output_buffer, &output_buffer_length); - dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); dma_channel_set_read_addr(dma_channel, output_buffer, false /* trigger */); + dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); + if (get_buffer_result == GET_BUFFER_DONE) { if (dma->loop) { audiosample_reset_buffer(dma->sample, dma->single_channel_output, dma->audio_channel); } else { // Set channel trigger to ourselves so we don't keep going. dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; - c->al1_ctrl = (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + c->al1_ctrl = + (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | + (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + + if (output_buffer_length == 0 && + !dma_channel_is_busy(dma->channel[0]) && + !dma_channel_is_busy(dma->channel[1])) { + // No data has been read, and both DMA channels have now finished, so it's safe to stop. + audio_dma_stop(dma); + dma->playing_in_progress = false; + } } } } // Playback should be shutdown before calling this. -audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, +audio_dma_result audio_dma_setup_playback( + audio_dma_t *dma, mp_obj_t sample, bool loop, bool single_channel_output, @@ -167,6 +202,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, uint8_t output_resolution, uint32_t output_register_address, uint8_t dma_trigger_source) { + // Use two DMA channels to play because the DMA can't wrap to itself without the // buffer being power of two aligned. int dma_channel_0_maybe = dma_claim_unused_channel(false); @@ -191,12 +227,15 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->unsigned_to_signed = false; dma->output_signed = output_signed; dma->sample_spacing = 1; - dma->first_channel_free = true; dma->output_resolution = output_resolution; dma->sample_resolution = audiosample_bits_per_sample(sample); + dma->output_register_address = output_register_address; + audiosample_reset_buffer(sample, single_channel_output, audio_channel); - bool single_buffer; + + bool single_buffer; // True if data fits in one single buffer. + bool samples_signed; uint32_t max_buffer_length; audiosample_get_buffer_structure(sample, single_channel_output, &single_buffer, &samples_signed, @@ -210,22 +249,25 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->sample_spacing > 1 || (dma->sample_resolution != dma->output_resolution)) { max_buffer_length /= dma->sample_spacing; - dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); - if (dma->first_buffer == NULL) { + } + + dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], max_buffer_length); + dma->buffer_length[0] = max_buffer_length; + if (dma->buffer[0] == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + + if (!single_buffer) { + dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], max_buffer_length); + dma->buffer_length[1] = max_buffer_length; + if (dma->buffer[1] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } - - dma->first_buffer_free = true; - if (!single_buffer) { - dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); - if (dma->second_buffer == NULL) { - return AUDIO_DMA_MEMORY_ERROR; - } - } - dma->signed_to_unsigned = !output_signed && samples_signed; - dma->unsigned_to_signed = output_signed && !samples_signed; } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + if (output_resolution > 8) { dma->output_size = 2; } else { @@ -248,9 +290,11 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, channel_config_set_dreq(&c, dma_trigger_source); channel_config_set_read_increment(&c, true); channel_config_set_write_increment(&c, false); + // Chain to the other channel by default. channel_config_set_chain_to(&c, dma->channel[(i + 1) % 2]); dma_channel_set_config(dma->channel[i], &c, false /* trigger */); + dma_channel_set_write_addr(dma->channel[i], (void *)output_register_address, false /* trigger */); } @@ -260,9 +304,9 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, MP_STATE_PORT(playing_audio)[dma->channel[1]] = dma; // Load the first two blocks up front. - audio_dma_load_next_block(dma); + audio_dma_load_next_block(dma, 0); if (!single_buffer) { - audio_dma_load_next_block(dma); + audio_dma_load_next_block(dma, 1); } // Special case the DMA for a single buffer. It's commonly used for a single wave length of sound @@ -279,16 +323,17 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, channel_config_set_chain_to(&c, dma->channel[1]); // Chain to ourselves so we stop. dma_channel_configure(dma->channel[1], &c, &dma_hw->ch[dma->channel[0]].al3_read_addr_trig, // write address - &dma->first_buffer, // read address + &dma->buffer[0], // read address 1, // transaction count false); // trigger } else { - // Enable our DMA channels on DMA0 to the CPU. This will wake us up when + // Enable our DMA channels on DMA_IRQ_0 to the CPU. This will wake us up when // we're WFI. dma_hw->inte0 |= (1 << dma->channel[0]) | (1 << dma->channel[1]); irq_set_mask_enabled(1 << DMA_IRQ_0, true); } + dma->playing_in_progress = true; dma_channel_start(dma->channel[0]); return AUDIO_DMA_OK; @@ -296,7 +341,14 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, void audio_dma_stop(audio_dma_t *dma) { // Disable our interrupts. - dma_hw->inte0 &= ~((1 << dma->channel[0]) | (1 << dma->channel[1])); + uint32_t channel_mask = 0; + if (dma->channel[0] < NUM_DMA_CHANNELS) { + channel_mask |= 1 << dma->channel[0]; + } + if (dma->channel[1] < NUM_DMA_CHANNELS) { + channel_mask |= 1 << dma->channel[1]; + } + dma_hw->inte0 &= ~channel_mask; irq_set_mask_enabled(1 << DMA_IRQ_0, false); // Run any remaining audio tasks because we remove ourselves from @@ -305,6 +357,10 @@ void audio_dma_stop(audio_dma_t *dma) { for (size_t i = 0; i < 2; i++) { size_t channel = dma->channel[i]; + if (channel == NUM_DMA_CHANNELS) { + // Channel not in use. + continue; + } dma_channel_config c = dma_channel_get_default_config(dma->channel[i]); channel_config_set_enable(&c, false); @@ -313,6 +369,7 @@ void audio_dma_stop(audio_dma_t *dma) { if (dma_channel_is_busy(channel)) { dma_channel_abort(channel); } + dma_channel_set_read_addr(channel, NULL, false /* trigger */); dma_channel_set_write_addr(channel, NULL, false /* trigger */); dma_channel_set_trans_count(channel, 0, false /* trigger */); @@ -320,6 +377,7 @@ void audio_dma_stop(audio_dma_t *dma) { MP_STATE_PORT(playing_audio)[channel] = NULL; dma->channel[i] = NUM_DMA_CHANNELS; } + dma->playing_in_progress = false; // Hold onto our buffers. } @@ -344,7 +402,7 @@ void audio_dma_resume(audio_dma_t *dma) { } bool audio_dma_get_paused(audio_dma_t *dma) { - if (dma->channel[0] >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->channel[0] >= NUM_DMA_CHANNELS) { return false; } uint32_t control = dma_hw->ch[dma->channel[0]].ctrl_trig; @@ -353,30 +411,26 @@ bool audio_dma_get_paused(audio_dma_t *dma) { } void audio_dma_init(audio_dma_t *dma) { - dma->first_buffer = NULL; - dma->second_buffer = NULL; + dma->buffer[0] = NULL; + dma->buffer[1] = NULL; + dma->channel[0] = NUM_DMA_CHANNELS; dma->channel[1] = NUM_DMA_CHANNELS; } void audio_dma_deinit(audio_dma_t *dma) { - m_free(dma->first_buffer); - dma->first_buffer = NULL; + m_free(dma->buffer[0]); + dma->buffer[0] = NULL; - m_free(dma->second_buffer); - dma->second_buffer = NULL; + m_free(dma->buffer[1]); + dma->buffer[1] = NULL; } bool audio_dma_get_playing(audio_dma_t *dma) { if (dma->channel[0] == NUM_DMA_CHANNELS) { return false; } - if (!dma_channel_is_busy(dma->channel[0]) && - !dma_channel_is_busy(dma->channel[1])) { - return false; - } - - return true; + return dma->playing_in_progress; } // WARN(tannewt): DO NOT print from here, or anything it calls. Printing calls @@ -389,7 +443,25 @@ STATIC void dma_callback_fun(void *arg) { return; } - audio_dma_load_next_block(dma); + common_hal_mcu_disable_interrupts(); + uint32_t channels_to_load_mask = dma->channels_to_load_mask; + dma->channels_to_load_mask = 0; + common_hal_mcu_enable_interrupts(); + + // Load the blocks for the requested channels. + uint32_t channel = 0; + while (channels_to_load_mask) { + if (channels_to_load_mask & 1) { + if (dma->channel[0] == channel) { + audio_dma_load_next_block(dma, 0); + } + if (dma->channel[1] == channel) { + audio_dma_load_next_block(dma, 1); + } + } + channels_to_load_mask >>= 1; + channel++; + } } void isr_dma_0(void) { @@ -397,6 +469,8 @@ void isr_dma_0(void) { uint32_t mask = 1 << i; if ((dma_hw->intr & mask) != 0 && MP_STATE_PORT(playing_audio)[i] != NULL) { audio_dma_t *dma = MP_STATE_PORT(playing_audio)[i]; + // Record all channels whose DMA has completed; they need loading. + dma->channels_to_load_mask |= mask; background_callback_add(&dma->callback, dma_callback_fun, (void *)dma); dma_hw->ints0 = mask; } diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index f84f6debeb..0ca911d337 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -43,12 +43,13 @@ typedef struct { bool signed_to_unsigned; bool unsigned_to_signed; bool output_signed; - bool first_channel_free; - bool first_buffer_free; + bool playing_in_progress; uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits - uint8_t *first_buffer; - uint8_t *second_buffer; + uint8_t *buffer[2]; + size_t buffer_length[2]; + uint32_t channels_to_load_mask; + uint32_t output_register_address; background_callback_t callback; } audio_dma_t; diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_itsybitsy_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 214662e331..2882e57922 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -69,7 +69,7 @@ void board_init(void) { &pin_GPIO24, // Command or data &pin_GPIO22, // Chip select &pin_GPIO23, // Reset - 1000000, // Baudrate + 10000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_macropad_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/pins.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/pins.c index f5ff3618c9..0f3d20c849 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/pins.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/pins.c @@ -17,7 +17,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_SPEAKER_SHUTDOWN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_ENCODER_SWITCH), MP_ROM_PTR(&pin_GPIO0) }, diff --git a/ports/raspberrypi/boards/adafruit_qt2040_trinkey/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_qtpy_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_qtpy_rp2040/pico-sdk-configboard.h @@ -0,0 +1,4 @@ +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/arduino_nano_rp2040_connect/pico-sdk-configboard.h b/ports/raspberrypi/boards/arduino_nano_rp2040_connect/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/arduino_nano_rp2040_connect/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/common-hal/busio/OneWire.h b/ports/raspberrypi/boards/pimoroni_interstate75/board.c similarity index 83% rename from ports/raspberrypi/common-hal/busio/OneWire.h rename to ports/raspberrypi/boards/pimoroni_interstate75/board.c index e27723ab2c..de6e424ed9 100644 --- a/ports/raspberrypi/common-hal/busio/OneWire.h +++ b/ports/raspberrypi/boards/pimoroni_interstate75/board.c @@ -24,10 +24,17 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_ONEWIRE_H +#include "supervisor/board.h" -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +void board_init(void) { +} -#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_BUSIO_ONEWIRE_H +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h new file mode 100644 index 0000000000..052c47fa68 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Interstate 75" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk new file mode 100644 index 0000000000..b52b31a9d9 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x1009 +USB_PRODUCT = "Interstate 75" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c new file mode 100644 index 0000000000..6e3e1a57b7 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c @@ -0,0 +1,52 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_R0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_B0), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_R1), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_B1), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_ROW_A), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_ROW_B), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_ROW_C), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_ROW_D), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_ROW_E), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LAT), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_OE), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { 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_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h index ecc127db68..0641aed52d 100644 --- a/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/mpconfigboard.h @@ -1,39 +1,8 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Keybow 2040" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_SW0 (&pin_GPIO21) -#define MICROPY_HW_SW1 (&pin_GPIO20) -#define MICROPY_HW_SW2 (&pin_GPIO19) -#define MICROPY_HW_SW3 (&pin_GPIO18) -#define MICROPY_HW_SW4 (&pin_GPIO17) -#define MICROPY_HW_SW5 (&pin_GPIO16) -#define MICROPY_HW_SW6 (&pin_GPIO15) -#define MICROPY_HW_SW7 (&pin_GPIO14) -#define MICROPY_HW_SW8 (&pin_GPIO13) -#define MICROPY_HW_SW9 (&pin_GPIO12) -#define MICROPY_HW_SW10 (&pin_GPIO11) -#define MICROPY_HW_SW11 (&pin_GPIO10) -#define MICROPY_HW_SW12 (&pin_GPIO9) -#define MICROPY_HW_SW13 (&pin_GPIO8) -#define MICROPY_HW_SW14 (&pin_GPIO7) -#define MICROPY_HW_SW15 (&pin_GPIO6) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - -#define MICROPY_HW_I2C_INT (&pin_GPIO3) - #define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) - -// These pins are unconnected -#define IGNORE_PIN_GPIO2 1 -#define IGNORE_PIN_GPIO22 1 -#define IGNORE_PIN_GPIO24 1 -#define IGNORE_PIN_GPIO25 1 -#define IGNORE_PIN_GPIO26 1 -#define IGNORE_PIN_GPIO27 1 -#define IGNORE_PIN_GPIO28 1 -#define IGNORE_PIN_GPIO29 1 diff --git a/ports/raspberrypi/boards/pimoroni_keybow2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_keybow2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_keybow2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_pga2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_pga2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pga2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h index 4261b9e006..a8e5d4bb15 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/mpconfigboard.h @@ -1,10 +1,5 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo (16MB)" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_VBUS_DETECT (&pin_GPIO24) -#define MICROPY_HW_BAT_SENSE (&pin_GPIO29) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - #define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_16mb/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h index e34a05abf2..7241b3bd56 100644 --- a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/mpconfigboard.h @@ -1,10 +1,5 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Pico LiPo (4MB)" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_VBUS_DETECT (&pin_GPIO24) -#define MICROPY_HW_BAT_SENSE (&pin_GPIO29) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - #define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) diff --git a/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picolipo_4mb/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h index 97ea17376d..7c39848256 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_picosystem/mpconfigboard.h @@ -1,48 +1,13 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni PicoSystem" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_VBUS_DETECT (&pin_GPIO2) - -#define MICROPY_HW_LCD_RESET (&pin_GPIO4) -#define MICROPY_HW_LCD_CS (&pin_GPIO5) -#define MICROPY_HW_LCD_SCLK (&pin_GPIO6) -#define MICROPY_HW_LCD_MOSI (&pin_GPIO7) -#define MICROPY_HW_LCD_VSYNC (&pin_GPIO8) -#define MICROPY_HW_LCD_DS (&pin_GPIO9) - -#define MICROPY_HW_AUDIO (&pin_GPIO11) -#define MICROPY_HW_BACKLIGHT (&pin_GPIO12) -#define MICROPY_HW_VBUS_DETECT (&pin_GPIO2) - #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO13) #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO14) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO15) -#define MICROPY_HW_SW_Y (&pin_GPIO16) -#define MICROPY_HW_SW_X (&pin_GPIO17) -#define MICROPY_HW_SW_A (&pin_GPIO18) -#define MICROPY_HW_SW_B (&pin_GPIO19) - -#define MICROPY_HW_SW_DOWN (&pin_GPIO20) -#define MICROPY_HW_SW_RIGHT (&pin_GPIO21) -#define MICROPY_HW_SW_LEFT (&pin_GPIO22) -#define MICROPY_HW_SW_UP (&pin_GPIO23) - -#define MICROPY_HW_CHARGE_STAT (&pin_GPIO24) - -#define MICROPY_HW_BAT_SENSE (&pin_GPIO26) - #define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) - -// These pins are unconnected -#define IGNORE_PIN_GPIO3 1 -#define IGNORE_PIN_GPIO10 1 -#define IGNORE_PIN_GPIO25 1 -#define IGNORE_PIN_GPIO27 1 -#define IGNORE_PIN_GPIO28 1 -#define IGNORE_PIN_GPIO29 1 diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_picosystem/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_picosystem/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/board.c b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c new file mode 100644 index 0000000000..de6e424ed9 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c @@ -0,0 +1,40 @@ +/* + * 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) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h new file mode 100644 index 0000000000..b8e48a26a2 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h @@ -0,0 +1,10 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk new file mode 100644 index 0000000000..10bfb5cc87 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x100a +USB_PRODUCT = "Plasma 2040" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c new file mode 100644 index 0000000000..e4e686da9d --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_DATA), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { 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_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h index 29bde18060..4184f35a7a 100644 --- a/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/mpconfigboard.h @@ -5,21 +5,3 @@ #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO18) #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO19) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO20) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - -// These pins are unconnected -#define IGNORE_PIN_GPIO8 1 -#define IGNORE_PIN_GPIO9 1 -#define IGNORE_PIN_GPIO10 1 -#define IGNORE_PIN_GPIO11 1 -#define IGNORE_PIN_GPIO12 1 -#define IGNORE_PIN_GPIO13 1 -#define IGNORE_PIN_GPIO14 1 -#define IGNORE_PIN_GPIO15 1 -#define IGNORE_PIN_GPIO16 1 -#define IGNORE_PIN_GPIO17 1 -#define IGNORE_PIN_GPIO21 1 -#define IGNORE_PIN_GPIO22 1 -#define IGNORE_PIN_GPIO24 1 -#define IGNORE_PIN_GPIO25 1 diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_tiny2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c b/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c index de79ee7320..1660de058e 100644 --- a/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c +++ b/ports/raspberrypi/boards/pimoroni_tiny2040/pins.c @@ -31,9 +31,5 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, - - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico/pico-sdk-configboard.h b/ports/raspberrypi/boards/raspberry_pi_pico/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h index d7dd7a6376..edeaf2e039 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h @@ -1,12 +1,15 @@ -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod ATP - RP2040" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod RP2040 Processor" #define MICROPY_HW_MCU_NAME "rp2040" +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk index 2ed559d8db..90f05a1754 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x1B4F USB_PID = 0x0024 -USB_PRODUCT = "MicroMod RP2040" -USB_MANUFACTURER = "SparkFun" +USB_PRODUCT = "SparkFun MicroMod RP2040 Processor" +USB_MANUFACTURER = "SparkFun Electronics" CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c index 90069a7e6f..ea9d38402c 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c @@ -1,105 +1,223 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * 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/board/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - // D (Digital only) pins (D0,D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO6) }, // GPIO6 - D0 - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // GPIO7 - D1 + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A (ADC) pins (A0,A1) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, // GPIO26 - A0 | ADC0 - { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_GPIO26) }, // ADC0 alias - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, // GPIO27 - A1 | ADC1 - { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_GPIO27) }, // ADC1 alias + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + // Note: GPIO25 is connected to both the status LED and edge connector pin + // G10, which doesn't comply with the requirement above... + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod LED (GPIO25) - // G (General/BUS) pins (G0-G7, G8 NC, G9-G10, G11 NC) - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO16) }, // GPIO16 - G0 | BUS0 - { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_GPIO16) }, // BUS0 alias - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO17) }, // GPIO17 - G1 | BUS1 - { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_GPIO17) }, // BUS1 alias - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO18) }, // GPIO18 - G2 | BUS2 - { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_GPIO18) }, // BUS2 alias - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO19) }, // GPIO19 - G3 | BUS3 - { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_GPIO19) }, // BUS3 alias - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - G4 | BUS4 | SPI_CIPO - { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_GPIO20) }, // BUS4 alias - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - G5 | BUS5 | SPI_CS - { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_GPIO21) }, // BUS5 alias - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - G6 | BUS6 | SPI_SCK - { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_GPIO22) }, // BUS6 alias - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - G7 | BUS7 | SPI_COPI - { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_GPIO23) }, // BUS7 alias - // NC - G8 - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO28) }, // GPIO28- G9 | BUS9 | ADC_D- | CAM_HSYNC - { MP_ROM_QSTR(MP_QSTR_BUS9), MP_ROM_PTR(&pin_GPIO28) }, // BUS9 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_GPIO28) }, // ADC_DM alias - { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_GPIO28) }, // CAM_HSYNC alias - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - G10 | BUS10 | ADC_D+ | CAM_VSYNC - { MP_ROM_QSTR(MP_QSTR_BUS10), MP_ROM_PTR(&pin_GPIO25) }, // BUS10 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_GPIO25) }, // ADC_DP alias - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO25) }, // CAM_VSYNC alias - // NC - G11 + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) - // PWM pins (PWM0,PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO13) }, // GPIO13 - PWM0 - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - PWM1 | AUD_MCLK + // MicroMod +3.3V enable pin + // { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR() }, // MicroMod 3.3V_EN (not connected) - // AUD (audio) - { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - AUD_MCLK | PWM1 - { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_GPIO10) }, // GPIO10 - AUD_OUT | SDIO_DAT2 - { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_GPIO11) }, // GPIO11 - AUD_IN | SDIO_DAT1 - { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - AUD_LRCLK | CTS1 - { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - AUD_BCLK | UART_RTS1 + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_GPIO29) }, // MicroMod BATT_VIN/3 (GPIO29) - // Battery Voltage Monitor - { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_GPIO29) }, // GPIO29 - BATT_VIN/3 (ADC03) + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (RP2040 has a dedicated HW RUN pin) + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (RP2040 does not have a dedicated BOOT pin) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, // GPIO4 - SDA - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, // GPIO5 - SCL + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR() }, // MicroMod USB_D- (RP2040 has a dedicated HW USB_DM pin) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR() }, // MicroMod USB_D+ (RP2040 has a dedicated HW USB_DP pin) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_GPIO8) }, // GPIO9 - I2C_INT | TX2 + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (RP2040 has a dedicated HW USB_DM pin) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (RP2040 has a dedicated HW USB_DP pin) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - CIPO | SPI_CIPO | G4 - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, // MISO alias - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - COPI | SPI_COPI | G7 - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // MOSI alias - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - SCK | SPI_SCK | G6 - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - /CS | SPI_/CS | G5 + // MicroMod CAN pins + // { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR() }, // MicroMod CAN_RX (not supported) + // { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR() }, // MicroMod CAN_TX (not supported) - // SDI/SPI1 - { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO14) }, // GPIO14 - SDIO SCK | SDIO_CLK - { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_GPIO14) }, // SPI_SCK1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO15) }, // GPIO15 - SDIO CMD | SDIO_CMD - { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_GPIO15) },// SPI_COPI1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO12) },// GPIO12 - SDIO DATA0 | SDIO_DATA0 - { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_GPIO12) }, // SPI_CIPO1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO11) },// GPIO11 - SDIO DATA1 | SDIO_DATA1 | AUD_IN - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO10) },// GPIO10 - SDIO DATA2 | SDIO_DATA2 | AUD_OUT - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO9) },// GPIO9 - SDIO DATA3 | SDIO_DATA3 | SPI_CS1 - { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_GPIO9) }, // SPI_CS1 alias + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // Status LED - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - LED_BUILTIN | STAT | Blue LED | G10 + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_GPIO0) }, // MicroMod UART_TX1 | CircuitPython TX (GPIO0) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_GPIO1) }, // MicroMod UART_RX1 | CircuitPython RX (GPIO1) + { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod RTS1 (GPIO3) + { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod CTS1 (GPIO2) - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, // GPIO1 - UART RX | UART_RX1 | RX1 - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO1) }, // RX1 alias - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, // GPIO0 - UART TX | UART_TX1 | TX1 - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO0) }, // TX1 alias - { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - UART CTS | CTS1 (TRACEDATA3) - { MP_ROM_QSTR(MP_QSTR_CTS1), MP_ROM_PTR(&pin_GPIO2) }, // CTS1 alias - { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - UART RTS | RTS1 - { MP_ROM_QSTR(MP_QSTR_RTS1), MP_ROM_PTR(&pin_GPIO3) }, // RTS1 alias + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, // CircuitPython TX | MicroMod UART_TX1 (GPIO0) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, // CircuitPython RX | MicroMod UART_RX1 (GPIO1) - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO9) }, // GPIO9 - UART RX | UART_RX2 | RX2 | SDIO_DAT3 | SPI_CS1 - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO8) }, // GPIO8 - UART TX | UART_TX2 | TX2 | I2C_INT + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_GPIO8) }, // MicroMod UART_TX2 (GPIO8) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod UART_RX2 (GPIO9) - // Board objects - { 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) }, + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO4) }, // MicroMod I2C_SDA | CircuitPython SDA (GPIO4) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO5) }, // MicroMod I2C_SCL | CircuitPython SCL (GPIO5) + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, // CircuitPython SDA | MicroMod I2C_SDA (GPIO4) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, // CircuitPython SCL | MicroMod I2C_SCL (GPIO5) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_GPIO8) }, // MicroMod I2C_INT (GPIO8) + + // MicroMod I2C1 pins + // { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR() }, // MicroMod I2C_SDA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR() }, // MicroMod I2C_SCL1 (not connected) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod SPI_CIPO | CircuitPython CIPO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod SPI_MISO | CircuitPython MISO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod SPI_MOSI | CircuitPython MOSI (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (GPIO22) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod SPI_CS | CircuitPython CS (GPIO21) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // CircuitPython CIPO | MicroMod SPI_CIPO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, // CircuitPython MISO | MicroMod SPI_MISO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_GPIO23) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (GPIO23) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // CircuitPython MOSI | MicroMod SPI_MOSI (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (GPIO22) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, // CircuitPython CS | MicroMod SPI_CS (GPIO21) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod LED_DAT | SPI_COPI + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod LED_CLK | SPI_SCK + + // MicroMod SDIO pins + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO14) }, // MicroMod SDIO_SCK | SPI_SCK1 (GPIO14) + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SDIO_CMD | SPI_COPI1 (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod SDIO_DATA1 (GPIO11) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod SDIO_DATA2 (GPIO10) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod SDIO_DATA3 | SPI_CS1 (GPIO9) + + // MicroMod SPI1 pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SPI_MISO1 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SPI_COPI1 | SDIO_CMD (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SPI_MOSI1 (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_GPIO14) }, // MicroMod SPI_SCK1 | SDIO_SCK (GPIO14) + { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod SPI_CS1 | SDIO_DATA3 (GPIO9) + + // MicroMod audio pins + { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_GPIO24) }, // MicroMod AUD_MCLK (GPIO24) + { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (GPIO3) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (GPIO3) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (GPIO3) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (GPIO2) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (GPIO3) + + // MicroMod SWD pins + // { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR() }, // MicroMod SWDIO (RP2040 has a dedicated HW SWDIO pin) + // { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR() }, // MicroMod SWDCK (RP2040 has a dedicated HW SWCLK pin) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not supported) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, // MicroMod A0 (GPIO26) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, // MicroMod A1 (GPIO27) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO13) }, // MicroMod PWM0 (GPIO13) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO24) }, // MicroMod PWM1 (GPIO24) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO6) }, // MicroMod D0 (GPIO6) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // MicroMod D1 | CAM_TRIG (GPIO7) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO16) }, // MicroMod G0 | BUS0 (GPIO16) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO17) }, // MicroMod G1 | BUS1 (GPIO17) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO18) }, // MicroMod G2 | BUS2 (GPIO18) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO19) }, // MicroMod G3 | BUS3 (GPIO19) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod G4 | BUS4 (GPIO20) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod G5 | BUS5 (GPIO21) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod G6 | BUS6 (GPIO22) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod G7 | BUS7 (GPIO23) + // { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR() }, // MicroMod G8 (not connected) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (GPIO28) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (GPIO25) + // { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR() }, // MicroMod G11 | SWO (not connected) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_GPIO16) }, // MicroMod BUS0 | G0 (GPIO16) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_GPIO17) }, // MicroMod BUS1 | G1 (GPIO17) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_GPIO18) }, // MicroMod BUS2 | G2 (GPIO18) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_GPIO19) }, // MicroMod BUS3 | G3 (GPIO19) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod BUS4 | G4 (GPIO20) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod BUS5 | G5 (GPIO21) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod BUS6 | G6 (GPIO22) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod BUS7 | G7 (GPIO23) + + // MicroMod differential ADC input pins (not supported by RP2040) + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (GPIO28) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (GPIO25) + + // MicroMod camera pins + { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (GPIO10) + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (GPIO11) + { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_GPIO7) }, // MicroMod CAM_TRIG | D1 (GPIO7) + { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod CAM_HSYNC | ADC_D- | G9 (GPIO28) + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (GPIO25) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c index 15a7cd523b..425b65e601 100644 --- a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c +++ b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c @@ -117,7 +117,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, } // Use the state machine to manage pins. - common_hal_rp2pio_statemachine_construct(&self->state_machine, + common_hal_rp2pio_statemachine_construct( + &self->state_machine, program, program_len, 44100 * 32 * 6, // Clock at 44.1 khz to warm the DAC up. NULL, 0, diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index 3a8a7ef226..05246ef1be 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -38,7 +38,6 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" -#include "supervisor/shared/tick.h" #include "supervisor/shared/translate.h" #include "src/rp2040/hardware_structs/include/hardware/structs/dma.h" @@ -158,27 +157,6 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, tx_register += self->left_pwm.channel * sizeof(uint16_t); } - audio_dma_result result = audio_dma_setup_playback( - &self->dma, - sample, - loop, - false, // single channel - 0, // audio channel - false, // output signed - BITS_PER_SAMPLE, - (uint32_t)tx_register, // output register: PWM cc register - 0x3b + pacing_timer); // data request line - - if (result == AUDIO_DMA_DMA_BUSY) { - common_hal_audiopwmio_pwmaudioout_stop(self); - mp_raise_RuntimeError(translate("No DMA channel found")); - } - if (result == AUDIO_DMA_MEMORY_ERROR) { - common_hal_audiopwmio_pwmaudioout_stop(self); - mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); - } - - // OK! We got all of the resources we need and dma is ready. self->pacing_timer = pacing_timer; // Playback with two independent clocks. One is the sample rate which @@ -215,6 +193,27 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, } dma_hw->timer[pacing_timer] = best_numerator << 16 | best_denominator; + + audio_dma_result result = audio_dma_setup_playback( + &self->dma, + sample, + loop, + false, // single channel + 0, // audio channel + false, // output signed + BITS_PER_SAMPLE, + (uint32_t)tx_register, // output register: PWM cc register + 0x3b + pacing_timer); // data request line + + if (result == AUDIO_DMA_DMA_BUSY) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(translate("No DMA channel found")); + } + if (result == AUDIO_DMA_MEMORY_ERROR) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); + } + // OK! We got all of the resources we need and dma is ready. } void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) { @@ -226,9 +225,11 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) audio_dma_stop(&self->dma); // Set to quiescent level. - pwm_hw->slice[self->left_pwm.slice].cc = self->quiescent_value; + common_hal_pwmio_pwmout_set_duty_cycle(&self->left_pwm, self->quiescent_value); + pwmio_pwmout_set_top(&self->left_pwm, PWM_TOP); if (self->stereo) { - pwm_hw->slice[self->right_pwm.slice].cc = self->quiescent_value; + common_hal_pwmio_pwmout_set_duty_cycle(&self->right_pwm, self->quiescent_value); + pwmio_pwmout_set_top(&self->right_pwm, PWM_TOP); } } diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index a72675d6b6..96038b4241 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -59,9 +59,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, 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]; + size_t scl_instance = (scl->number / 2) % 2; + size_t sda_instance = (sda->number / 2) % 2; + if (scl->number % 2 == 1 && sda->number % 2 == 0 && scl_instance == sda_instance) { + self->peripheral = i2c[sda_instance]; } if (self->peripheral == NULL) { mp_raise_ValueError(translate("Invalid pins")); diff --git a/ports/raspberrypi/sdk_config/pico/config_autogen.h b/ports/raspberrypi/sdk_config/pico/config_autogen.h index a8ff324e1c..a29ccb458a 100644 --- a/ports/raspberrypi/sdk_config/pico/config_autogen.h +++ b/ports/raspberrypi/sdk_config/pico/config_autogen.h @@ -1,5 +1,7 @@ #pragma once +#include "pico-sdk-configboard.h" + // alphabetized #define LIB_PICO_BINARY_INFO (0) #define LIB_PICO_PRINTF_NONE (0) diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/board.c b/ports/stm/boards/sparkfun_stm32f405_micromod/board.c new file mode 100644 index 0000000000..f8e462f938 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/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/sparkfun_stm32f405_micromod/mpconfigboard.h b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h new file mode 100644 index 0000000000..ed3a643322 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Chris Wilson + * + * 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 "SparkFun STM32 MicroMod Processor" +#define MICROPY_HW_MCU_NAME "STM32F405RG" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (0x4000) + +#define HSE_VALUE ((uint32_t)12000000) +#define LSE_VALUE ((uint32_t)32768) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (1) + +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_PA15) + +// On-board SPI flash +#define SPI_FLASH_MOSI_PIN (&pin_PC12) +#define SPI_FLASH_MISO_PIN (&pin_PC11) +#define SPI_FLASH_SCK_PIN (&pin_PC10) +#define SPI_FLASH_CS_PIN (&pin_PC03) + +// Bootloader only +#ifdef UF2_BOOTLOADER_ENABLED + #define BOARD_VTOR_DEFER (1) // Leave VTOR relocation to bootloader +#endif + +#define DEFAULT_I2C_BUS_SCL (&pin_PB10) +#define DEFAULT_I2C_BUS_SDA (&pin_PB11) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA06) + +#define DEFAULT_UART_BUS_RX (&pin_PA03) +#define DEFAULT_UART_BUS_TX (&pin_PA02) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA11 (1) +#define IGNORE_PIN_PA12 (1) diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk new file mode 100644 index 0000000000..d1df685c67 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk @@ -0,0 +1,19 @@ +USB_VID = 0X1B4F +USB_PID = 0x0027 +USB_PRODUCT = "SparkFun STM32 MicroMod Processor" +USB_MANUFACTURER = "SparkFun Electronics" + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = W25Q128JVxM + +MCU_SERIES = F4 +MCU_VARIANT = STM32F405xx +MCU_PACKAGE = LQFP64 + +LD_COMMON = boards/common_default.ld +LD_DEFAULT = boards/STM32F405_default.ld +# UF2 boot option +LD_BOOT = boards/STM32F405_boot.ld +UF2_OFFSET = 0x8010000 + +CIRCUITPY_RGBMATRIX ?= 1 diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c b/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c new file mode 100644 index 0000000000..2379e9a371 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c @@ -0,0 +1,224 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Chris Wilson + * + * 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/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs + + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA15) }, // MicroMod LED (PA15) + + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) + + // MicroMod +3.3V enable pin + // { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR() }, // MicroMod 3.3V_EN (not connected) + + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_PA01) }, // MicroMod BATT_VIN/3 (PA1) + + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (STM32 has a dedicated HW NRST pin) + + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (STM32 has a dedicated HW BOOT0 pin) + + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. See explicit ignores in mpconfigboard.h. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR(&pin_PA11) }, // MicroMod USB_D- (PA11) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR(&pin_PA12) }, // MicroMod USB_D+ (PA12) + + // MicroMod USB host pins + { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR(&pin_PB14) }, // MicroMod USBHOST_D- (PB14) + { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR(&pin_PB15) }, // MicroMod USBHOST_D+ (PB15) + + // MicroMod CAN pins + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB08) }, // MicroMod CAN_RX (PB8) + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB09) }, // MicroMod CAN_TX (PB9) + + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. + + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_PA02) }, // MicroMod UART_TX1 | CircuitPython TX (PA2) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_PA03) }, // MicroMod UART_RX1 | CircuitPython RX (PA3) + // { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR() }, // MicroMod RTS1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR() }, // MicroMod CTS1 (not connected) + + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA02) }, // CircuitPython TX | MicroMod UART_TX1 (PA2) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA03) }, // CircuitPython RX | MicroMod UART_RX1 (PA3) + + // MicroMod UART2 pins + // { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR() }, // MicroMod UART_TX2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR() }, // MicroMod UART_RX2 (not connected) + + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_PB11) }, // MicroMod I2C_SDA | CircuitPython SDA (PB11) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PB10) }, // MicroMod I2C_SCL | CircuitPython SCL (PB10) + + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB11) }, // CircuitPython SDA | MicroMod I2C_SDA (PB11) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB10) }, // CircuitPython SCL | MicroMod I2C_SCL (PB10) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PB01) }, // MicroMod I2C_INT (PB1) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_PB07) }, // MicroMod I2C_SDA1 (PB7) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_PB06) }, // MicroMod I2C_SCL1 (PB6) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_CIPO | CircuitPython CIPO (PA6) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_MISO | CircuitPython MISO (PA6) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (PA7) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_MOSI | CircuitPython MOSI (PA7) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (PA5) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_CS | CircuitPython CS (PC4) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython CIPO | MicroMod SPI_CIPO (PA6) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython MISO | MicroMod SPI_MISO (PA6) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA07) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (PA7) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA07) }, // CircuitPython MOSI | MicroMod SPI_MOSI (PA7) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (PA5) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA04) }, // CircuitPython CS | MicroMod SPI_CS (PC4) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_PA07) }, // MicroMod LED_DAT | SPI_COPI (PA7) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_PA05) }, // MicroMod LED_CLK | SPI_SCK (PA5) + + // MicroMod SDIO pins + // { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR() }, // MicroMod SDIO_SCK | SPI_SCK1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR() }, // MicroMod SDIO_CMD | SPI_COPI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR() }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR() }, // MicroMod SDIO_DATA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR() }, // MicroMod SDIO_DATA2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR() }, // MicroMod SDIO_DATA3 | SPI_CS1 (not connected) + + // MicroMod SPI1 pins + // { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR() }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR() }, // MicroMod SPI_MISO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR() }, // MicroMod SPI_COPI1 | SDIO_CMD (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR() }, // MicroMod SPI_MOSI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR() }, // MicroMod SPI_SCK1 | SDIO_SCK (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR() }, // MicroMod SPI_CS1 | SDIO_DATA3 (not connected) + + // MicroMod audio pins + // { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR() }, // MicroMod AUD_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (PB4) + // { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (PB5) + // { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA04) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (PA4) + // { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (PB3) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (PB4) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (PB5) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_PA04) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (PA4) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_PB03) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (PB3) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (PB4) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (PB5) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_PA04) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (PA4) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (PB3) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_PA04) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (PA4) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (PB3) + + // MicroMod SWD pins + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA13) }, // MicroMod SWDIO (PA13) + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA14) }, // MicroMod SWDCK (PA14) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not connected) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PC05) }, // MicroMod A0 (PC5) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, // MicroMod A1 (PB0) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PC06) }, // MicroMod PWM0 (PC6) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PC07) }, // MicroMod PWM1 (PC7) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PC00) }, // MicroMod D0 (PC0) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PC01) }, // MicroMod D1 | CAM_TRIG (PC1) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PD02) }, // MicroMod G0 | BUS0 (PD2) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA08) }, // MicroMod G1 | BUS1 (PA8) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PA00) }, // MicroMod G2 | BUS2 (PA0) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PC08) }, // MicroMod G3 | BUS3 (PC8) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PC09) }, // MicroMod G4 | BUS4 (PC9) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PC13) }, // MicroMod G5 | BUS5 (PC13) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PC02) }, // MicroMod G6 | BUS6 (PC2) + // { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR() }, // MicroMod G7 | BUS7 (not connected) + // { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR() }, // MicroMod G8 (not connected) + // { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR() }, // MicroMod G9 | ADC_D- | CAM_HSYNC (not connected) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_PB13) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (PB13) + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PB12) }, // MicroMod G11 | SWO (PB12) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_PD02) }, // MicroMod BUS0 | G0 (PD2) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_PA08) }, // MicroMod BUS1 | G1 (PA8) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_PA00) }, // MicroMod BUS2 | G2 (PA0) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_PC08) }, // MicroMod BUS3 | G3 (PC8) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_PC09) }, // MicroMod BUS4 | G4 (PC9) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_PC13) }, // MicroMod BUS5 | G5 (PC13) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_PC02) }, // MicroMod BUS6 | G6 (PC2) + // { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR() }, // MicroMod BUS7 | G7 (not connected) + + // MicroMod differential ADC input pins + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR() }, // MicroMod ADC_D- | G9 | CAM_HSYNC (not connected) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_PB13) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (PB13) + + // MicroMod camera pins + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_PB04) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (PB4) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_PB05) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (PB5) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_PC01) }, // MicroMod CAM_TRIG | D1 (PC1) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR() }, // MicroMod CAM_HSYNC | ADC_D- | G9 (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_PB13) }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (PB13) + + // Module-specific aliases (not part of the MicroMod spec) + { MP_ROM_QSTR(MP_QSTR_HOST_VBUS), MP_ROM_PTR(&pin_PB13) }, // HOST_VBUS | G10 | ADC_D+ | CAM_VSYNC (PB13) + { MP_ROM_QSTR(MP_QSTR_HOST_ID), MP_ROM_PTR(&pin_PB12) }, // HOST_ID | G11 | SWO (PB12) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.mk b/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.mk index dc1dfad0d6..db83a5ce6b 100644 --- a/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ce_blackpill/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x239A USB_PID = 0x806A USB_PRODUCT = "stm32f411ce blackpill" -USB_MANUFACTURER = "Unknown" +USB_MANUFACTURER = "WeAct" # SPI_FLASH_FILESYSTEM = 1 # EXTERNAL_FLASH_DEVICES = xxxxxx #See supervisor/shared/external_flash/devices.h for options diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk index 7ea5fc4a82..9da7163743 100644 --- a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x239A USB_PID = 0x006A USB_PRODUCT = "stm32f411ce blackpill with flash" -USB_MANUFACTURER = "Unknown" +USB_MANUFACTURER = "WeAct" SPI_FLASH_FILESYSTEM = 1 #See supervisor/shared/external_flash/devices.h for options @@ -16,3 +16,6 @@ MCU_PACKAGE = UFQFPN48 LD_COMMON = boards/common_default.ld LD_FILE = boards/STM32F411_nofs.ld + +# Too big for the flash +CIRCUITPY_ULAB = 0 diff --git a/ports/stm/common-hal/alarm/SleepMemory.c b/ports/stm/common-hal/alarm/SleepMemory.c index 3b89efbca3..dc19222d63 100644 --- a/ports/stm/common-hal/alarm/SleepMemory.c +++ b/ports/stm/common-hal/alarm/SleepMemory.c @@ -29,21 +29,45 @@ #include "py/runtime.h" #include "common-hal/alarm/SleepMemory.h" +#include STM32_HAL_H + +#define STM_BKPSRAM_SIZE 0x1000 +#define STM_BKPSRAM_START BKPSRAM_BASE + +STATIC bool initialized = false; + +STATIC void lazy_init(void) { + if (!initialized) { + __HAL_RCC_BKPSRAM_CLK_ENABLE(); + HAL_PWREx_EnableBkUpReg(); + HAL_PWR_EnableBkUpAccess(); + initialized = true; + } +} + void alarm_sleep_memory_reset(void) { } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - mp_raise_NotImplementedError(translate("Sleep Memory not available")); - return 0; + lazy_init(); + return STM_BKPSRAM_SIZE; } bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t *values, uint32_t len) { - mp_raise_NotImplementedError(translate("Sleep Memory not available")); - return false; + if (start_index + len > STM_BKPSRAM_SIZE) { + return false; + } + lazy_init(); + memcpy((uint8_t *)(STM_BKPSRAM_START + start_index), values, len); + return true; } void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t *values, uint32_t len) { - mp_raise_NotImplementedError(translate("Sleep Memory not available")); + if (start_index + len > STM_BKPSRAM_SIZE) { + return; + } + lazy_init(); + memcpy(values, (uint8_t *)(STM_BKPSRAM_START + start_index), len); return; } diff --git a/ports/stm/common-hal/canio/Listener.c b/ports/stm/common-hal/canio/Listener.c index 23634eba69..dc819180f9 100644 --- a/ports/stm/common-hal/canio/Listener.c +++ b/ports/stm/common-hal/canio/Listener.c @@ -30,6 +30,8 @@ #include "py/obj.h" #include "py/runtime.h" +#include "lib/utils/interrupt_char.h" + #include "common-hal/canio/__init__.h" #include "common-hal/canio/Listener.h" #include "shared-bindings/canio/Listener.h" @@ -272,6 +274,11 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { if (supervisor_ticks_ms64() > deadline) { return NULL; } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return NULL; + } } while (!common_hal_canio_listener_in_waiting(self)); } diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index aa554200bb..e9674a3ec2 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -21,5 +21,12 @@ MICROPY_VFS_LFS2 = 1 FROZEN_DIR=variants/coverage/frzstr FROZEN_MPY_DIR=variants/coverage/frzmpy +SRC_QRIO := $(patsubst ../../%,%,$(wildcard ../../shared-bindings/qrio/*.c ../../shared-module/qrio/*.c ../../lib/quirc/lib/*.c)) +$(info SRC_QRIO = $(SRC_QRIO)) +SRC_C += $(SRC_QRIO) + +CFLAGS += -DCIRCUITPY_QRIO=1 +$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h + SRC_C += coverage.c SRC_CXX += coveragecpp.cpp diff --git a/py/argcheck.c b/py/argcheck.c index 0d14c5eff2..ae779a1faa 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -197,7 +197,7 @@ mp_float_t mp_arg_validate_obj_float_non_negative(mp_obj_t float_in, mp_float_t size_t mp_arg_validate_length_with_name(mp_int_t i, size_t length, qstr arg_name, qstr length_name) { if (i != (mp_int_t)length) { - mp_raise_ValueError_varg(translate("%q length must be %q"), MP_QSTR_pressed, MP_QSTR_num_keys); + mp_raise_ValueError_varg(translate("%q length must be %q"), arg_name, length_name); } return (size_t)i; } diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 344ded80b0..8590c4beea 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -131,10 +131,7 @@ STATIC void mp_help_print_modules(void) { #if MICROPY_ENABLE_EXTERNAL_IMPORT // let the user know there may be other modules available from the filesystem - const compressed_string_t *compressed = translate("Plus any modules on the filesystem\n"); - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - mp_print_str(MP_PYTHON_PRINTER, decompressed); + mp_printf(MP_PYTHON_PRINTER, "%S", translate("Plus any modules on the filesystem\n")); #endif } #endif @@ -150,18 +147,10 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { const mp_obj_type_t *type = mp_obj_get_type(obj); // try to print something sensible about the given 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_cprintf(MP_PYTHON_PRINTER, translate("object ")); mp_obj_print(obj, PRINT_STR); - 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_cprintf(MP_PYTHON_PRINTER, translate(" is of type %q\n"), type->name); mp_map_t *map = NULL; if (type == &mp_type_module) { @@ -186,11 +175,9 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { STATIC mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { // print a general help message. Translate only works on single strings on one line. - const compressed_string_t *compressed = - translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"); - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - mp_printf(MP_PYTHON_PRINTER, decompressed, MICROPY_GIT_TAG); + mp_cprintf(MP_PYTHON_PRINTER, + translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"), + MICROPY_GIT_TAG); } else { // try to print something sensible about the given object mp_help_print_obj(args[0]); diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 938dcbd8b4..78fb255801 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -158,7 +158,7 @@ ifeq ($(CIRCUITPY_BUSDEVICE),1) SRC_PATTERNS += adafruit_bus_device/% endif ifeq ($(CIRCUITPY_BUSIO),1) -SRC_PATTERNS += busio/% bitbangio/OneWire.% +SRC_PATTERNS += busio/% endif ifeq ($(CIRCUITPY_CAMERA),1) SRC_PATTERNS += camera/% @@ -191,6 +191,9 @@ endif ifeq ($(CIRCUITPY_GAMEPADSHIFT),1) SRC_PATTERNS += gamepadshift/% endif +ifeq ($(CIRCUITPY_GETPASS),1) +SRC_PATTERNS += getpass/% +endif ifeq ($(CIRCUITPY_GNSS),1) SRC_PATTERNS += gnss/% endif @@ -218,6 +221,9 @@ endif ifeq ($(CIRCUITPY_NVM),1) SRC_PATTERNS += nvm/% endif +ifeq ($(CIRCUITPY_ONEWIREIO),1) +SRC_PATTERNS += onewireio/% +endif ifeq ($(CIRCUITPY_OS),1) SRC_PATTERNS += os/% endif @@ -227,6 +233,9 @@ endif ifeq ($(CIRCUITPY_PIXELBUF),1) SRC_PATTERNS += adafruit_pixelbuf/% endif +ifeq ($(CIRCUITPY_QRIO),1) +SRC_PATTERNS += qrio/% +endif ifeq ($(CIRCUITPY_RAINBOWIO),1) SRC_PATTERNS += rainbowio/% endif @@ -296,6 +305,9 @@ endif ifeq ($(CIRCUITPY_TOUCHIO),1) SRC_PATTERNS += touchio/% endif +ifeq ($(CIRCUITPY_TRACEBACK),1) +SRC_PATTERNS += traceback/% +endif ifeq ($(CIRCUITPY_UHEAP),1) SRC_PATTERNS += uheap/% endif @@ -445,6 +457,8 @@ $(filter $(SRC_PATTERNS), \ _eve/__init__.c \ camera/ImageFormat.c \ canio/Match.c \ + qrio/PixelPolicy.c \ + qrio/QRInfo.c \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ @@ -486,7 +500,6 @@ SRC_SHARED_MODULE_ALL = \ audiomp3/__init__.c \ audiopwmio/__init__.c \ bitbangio/I2C.c \ - bitbangio/OneWire.c \ bitbangio/SPI.c \ bitbangio/__init__.c \ bitmaptools/__init__.c \ @@ -495,7 +508,6 @@ SRC_SHARED_MODULE_ALL = \ adafruit_bus_device/__init__.c \ adafruit_bus_device/I2CDevice.c \ adafruit_bus_device/SPIDevice.c \ - busio/OneWire.c \ canio/Match.c \ canio/Message.c \ canio/RemoteTransmissionRequest.c \ @@ -515,6 +527,9 @@ SRC_SHARED_MODULE_ALL = \ fontio/__init__.c \ framebufferio/FramebufferDisplay.c \ framebufferio/__init__.c \ + gamepadshift/GamePadShift.c \ + gamepadshift/__init__.c \ + getpass/__init__.c \ ipaddress/IPv4Address.c \ ipaddress/__init__.c \ keypad/__init__.c \ @@ -523,21 +538,23 @@ SRC_SHARED_MODULE_ALL = \ keypad/KeyMatrix.c \ keypad/ShiftRegisterKeys.c \ keypad/Keys.c \ - sdcardio/SDCard.c \ - sdcardio/__init__.c \ - gamepadshift/GamePadShift.c \ - gamepadshift/__init__.c \ memorymonitor/__init__.c \ memorymonitor/AllocationAlarm.c \ memorymonitor/AllocationSize.c \ network/__init__.c \ msgpack/__init__.c \ + onewireio/__init__.c \ + onewireio/OneWire.c \ os/__init__.c \ + qrio/__init__.c \ + qrio/QRDecoder.c \ rainbowio/__init__.c \ random/__init__.c \ rgbmatrix/RGBMatrix.c \ rgbmatrix/__init__.c \ rotaryio/IncrementalEncoder.c \ + sdcardio/SDCard.c \ + sdcardio/__init__.c \ sharpdisplay/SharpMemoryFramebuffer.c \ sharpdisplay/__init__.c \ socket/__init__.c \ @@ -548,6 +565,7 @@ SRC_SHARED_MODULE_ALL = \ terminalio/Terminal.c \ terminalio/__init__.c \ time/__init__.c \ + traceback/__init__.c \ uheap/__init__.c \ ustack/__init__.c \ vectorio/Circle.c \ @@ -668,6 +686,11 @@ SRC_CIRCUITPY_COMMON = \ lib/utils/stdout_helpers.c \ lib/utils/sys_stdio_mphal.c +ifeq ($(CIRCUITPY_QRIO),1) +SRC_CIRCUITPY_COMMON += lib/quirc/lib/decode.c lib/quirc/lib/identify.c lib/quirc/lib/quirc.c lib/quirc/lib/version_db.c +$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h +endif + ifdef LD_TEMPLATE_FILE # Generate a linker script (.ld file) from a template, for those builds that use it. GENERATED_LD_FILE = $(BUILD)/$(notdir $(patsubst %.template.ld,%.ld,$(LD_TEMPLATE_FILE))) diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 7dfdf7f311..a7e57c832e 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -188,7 +188,9 @@ typedef long mp_off_t; // Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD) +#ifndef MICROPY_CPYTHON_COMPAT #define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) +#endif #define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_BUILTINS_POW3) #define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT) #define MICROPY_MODULE_WEAK_LINKS (0) @@ -490,6 +492,13 @@ extern const struct _mp_obj_module_t gamepadshift_module; #define GAMEPAD_ROOT_POINTERS #endif +#if CIRCUITPY_GETPASS +extern const struct _mp_obj_module_t getpass_module; +#define GETPASS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_getpass), (mp_obj_t)&getpass_module }, +#else +#define GETPASS_MODULE +#endif + #if CIRCUITPY_GNSS extern const struct _mp_obj_module_t gnss_module; #define GNSS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_gnss), (mp_obj_t)&gnss_module }, @@ -583,6 +592,13 @@ extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t nvm_module; #endif +#if CIRCUITPY_ONEWIREIO +extern const struct _mp_obj_module_t onewireio_module; +#define ONEWIREIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_onewireio), (mp_obj_t)&onewireio_module }, +#else +#define ONEWIREIO_MODULE +#endif + #if CIRCUITPY_OS extern const struct _mp_obj_module_t os_module; #define OS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, @@ -628,6 +644,8 @@ extern const struct _mp_obj_module_t pwmio_module; #define PWMIO_MODULE #endif +// CIRCUITPY_QRIO uses MP_REGISTER_MODULE + #if CIRCUITPY_RAINBOWIO extern const struct _mp_obj_module_t rainbowio_module; #define RAINBOWIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rainbowio), (mp_obj_t)&rainbowio_module }, @@ -770,6 +788,13 @@ extern const struct _mp_obj_module_t touchio_module; #define TOUCHIO_MODULE #endif +#if CIRCUITPY_TRACEBACK +extern const struct _mp_obj_module_t traceback_module; +#define TRACEBACK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_traceback), (mp_obj_t)&traceback_module }, +#else +#define TRACEBACK_MODULE +#endif + #if CIRCUITPY_UHEAP extern const struct _mp_obj_module_t uheap_module; #define UHEAP_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_uheap),(mp_obj_t)&uheap_module }, @@ -890,6 +915,7 @@ extern const struct _mp_obj_module_t msgpack_module; FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ GAMEPADSHIFT_MODULE \ + GETPASS_MODULE \ GNSS_MODULE \ I2CPERIPHERAL_MODULE \ IPADDRESS_MODULE \ @@ -901,6 +927,7 @@ extern const struct _mp_obj_module_t msgpack_module; MICROCONTROLLER_MODULE \ MSGPACK_MODULE \ NEOPIXEL_WRITE_MODULE \ + ONEWIREIO_MODULE \ PEW_MODULE \ PIXELBUF_MODULE \ PS2IO_MODULE \ @@ -925,6 +952,7 @@ extern const struct _mp_obj_module_t msgpack_module; SUPERVISOR_MODULE \ SYNTHIO_MODULE \ TOUCHIO_MODULE \ + TRACEBACK_MODULE \ UHEAP_MODULE \ USB_CDC_MODULE \ USB_HID_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 315d6ba52c..53030aec2c 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -124,9 +124,15 @@ CFLAGS += -DCIRCUITPY_BUILTINS_POW3=$(CIRCUITPY_BUILTINS_POW3) CIRCUITPY_BUSIO ?= 1 CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO) +# These two flags pretend to implement their class but raise a ValueError due to +# unsupported pins. This should be used sparingly on boards that don't break out +# generic IO but need parts of busio. CIRCUITPY_BUSIO_SPI ?= 1 CFLAGS += -DCIRCUITPY_BUSIO_SPI=$(CIRCUITPY_BUSIO_SPI) +CIRCUITPY_BUSIO_UART ?= 1 +CFLAGS += -DCIRCUITPY_BUSIO_UART=$(CIRCUITPY_BUSIO_UART) + CIRCUITPY_CAMERA ?= 0 CFLAGS += -DCIRCUITPY_CAMERA=$(CIRCUITPY_CAMERA) @@ -187,12 +193,18 @@ CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO) CIRCUITPY_GAMEPADSHIFT ?= 0 CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT) +CIRCUITPY_GETPASS ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_GETPASS=$(CIRCUITPY_GETPASS) + CIRCUITPY_GNSS ?= 0 CFLAGS += -DCIRCUITPY_GNSS=$(CIRCUITPY_GNSS) CIRCUITPY_I2CPERIPHERAL ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_I2CPERIPHERAL=$(CIRCUITPY_I2CPERIPHERAL) +CIRCUITPY_IMAGECAPTURE ?= 0 +CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) + CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS) @@ -220,12 +232,12 @@ CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE) CIRCUITPY_NVM ?= 1 CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM) +CIRCUITPY_ONEWIREIO ?= $(CIRCUITPY_BUSIO) +CFLAGS += -DCIRCUITPY_ONEWIREIO=$(CIRCUITPY_ONEWIREIO) + CIRCUITPY_OS ?= 1 CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) -CIRCUITPY_IMAGECAPTURE ?= 0 -CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) - CIRCUITPY_PEW ?= 0 CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW) @@ -242,6 +254,9 @@ CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO) CIRCUITPY_PWMIO ?= 1 CFLAGS += -DCIRCUITPY_PWMIO=$(CIRCUITPY_PWMIO) +CIRCUITPY_QRIO ?= $(CIRCUITPY_IMAGECAPTURE) +CFLAGS += -DCIRCUITPY_QRIO=$(CIRCUITPY_QRIO) + CIRCUITPY_RAINBOWIO ?= 1 CFLAGS += -DCIRCUITPY_RAINBOWIO=$(CIRCUITPY_RAINBOWIO) @@ -327,6 +342,9 @@ CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE) CIRCUITPY_TOUCHIO ?= 1 CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO) +CIRCUITPY_TRACEBACK ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_TRACEBACK=$(CIRCUITPY_TRACEBACK) + # For debugging. CIRCUITPY_UHEAP ?= 0 CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index d2a10d29db..74ad78c47d 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -333,12 +333,9 @@ def compute_huffman_coding(translations, compression_filename): bits_per_codepoint = 16 if max_ord > 255 else 8 values_type = "uint16_t" if max_ord > 255 else "uint8_t" - max_words_len = 160 if max_ord > 255 else 255 - - sum_len = 0 - while True: + while len(words) < max_words: # Until the dictionary is filled to capacity, use a heuristic to find - # the best "word" (3- to 9-gram) to add to it. + # the best "word" (2- to 11-gram) to add to it. # # The TextSplitter allows us to avoid considering parts of the text # that are already covered by a previously chosen word, for example @@ -369,7 +366,8 @@ def compute_huffman_coding(translations, compression_filename): # the Huffman tree bumps up the encoding lengths of all words in the # same subtree. In the extreme case when the new word is so frequent # that it gets a one-bit encoding, all other words will cost an extra - # bit each. + # bit each. This is empirically modeled by the constant factor added to + # cost, but the specific value used isn't "proven" to be correct. # # Another source of inaccuracy is that compressed strings end up # on byte boundaries, not bit boundaries, so saving 1 bit somewhere @@ -383,14 +381,14 @@ def compute_huffman_coding(translations, compression_filename): # The difference between the two is the estimated net savings, in bits. def est_net_savings(s, occ): savings = occ * (bit_length(s) - est_len(occ)) - cost = len(s) * bits_per_codepoint + cost = len(s) * bits_per_codepoint + 24 return savings - cost counter = collections.Counter() for t in texts: for (found, word) in extractor.iter_words(t): if not found: - for substr in iter_substrings(word, minlen=3, maxlen=9): + for substr in iter_substrings(word, minlen=2, maxlen=11): counter[substr] += 1 # Score the candidates we found. This is a semi-empirical formula that @@ -410,16 +408,9 @@ def compute_huffman_coding(translations, compression_filename): break word = scores[0][0] - - # If we can successfully add it to the dictionary, do so. Otherwise, - # we've filled the dictionary to capacity and are done. - if sum_len + len(word) - 2 > max_words_len: - break - if len(words) == max_words: - break words.append(word) - sum_len += len(word) - 2 + words.sort(key=len) extractor = TextSplitter(words) counter = collections.Counter() for t in texts: @@ -469,16 +460,15 @@ def compute_huffman_coding(translations, compression_filename): len(translation.encode("utf-8")) for (original, translation) in translations ) - wends = list(len(w) - 2 for w in words) - for i in range(1, len(wends)): - wends[i] += wends[i - 1] + maxlen = len(words[-1]) + minlen = len(words[0]) + wlencount = [len([None for w in words if len(w) == l]) for l in range(minlen, maxlen + 1)] with open(compression_filename, "w") as f: + f.write("typedef {} mchar_t;".format(values_type)) f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths)))) f.write( - "const {} values[] = {{ {} }};\n".format( - values_type, ", ".join(str(ord(u)) for u in values) - ) + "const mchar_t values[] = {{ {} }};\n".format(", ".join(str(ord(u)) for u in values)) ) f.write( "#define compress_max_length_bits ({})\n".format( @@ -486,13 +476,17 @@ def compute_huffman_coding(translations, compression_filename): ) ) f.write( - "const {} words[] = {{ {} }};\n".format( - values_type, ", ".join(str(ord(c)) for w in words for c in w) + "const mchar_t words[] = {{ {} }};\n".format( + ", ".join(str(ord(c)) for w in words for c in w) ) ) - f.write("const uint8_t wends[] = {{ {} }};\n".format(", ".join(str(p) for p in wends))) + f.write( + "const uint8_t wlencount[] = {{ {} }};\n".format(", ".join(str(p) for p in wlencount)) + ) f.write("#define word_start {}\n".format(word_start)) f.write("#define word_end {}\n".format(word_end)) + f.write("#define minlen {}\n".format(minlen)) + f.write("#define maxlen {}\n".format(maxlen)) return (values, lengths, words, canonical, extractor) diff --git a/py/modsys.c b/py/modsys.c index cbd1712920..484e29f411 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -120,25 +120,6 @@ STATIC mp_obj_t mp_sys_exit(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit); -STATIC mp_obj_t mp_sys_print_exception(size_t n_args, const mp_obj_t *args) { - #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES - void *stream_obj = &mp_sys_stdout_obj; - if (n_args > 1) { - mp_get_stream_raise(args[1], MP_STREAM_OP_WRITE); - stream_obj = MP_OBJ_TO_PTR(args[1]); - } - - mp_print_t print = {stream_obj, mp_stream_write_adaptor}; - mp_obj_print_exception(&print, args[0]); - #else - (void)n_args; - mp_obj_print_exception(&mp_plat_print, args[0]); - #endif - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception); - #if MICROPY_PY_SYS_EXC_INFO STATIC mp_obj_t mp_sys_exc_info(void) { mp_obj_t cur_exc = MP_OBJ_FROM_PTR(MP_STATE_VM(cur_exception)); diff --git a/py/mpprint.c b/py/mpprint.c index b99b5d658d..af485a50f2 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -376,6 +376,13 @@ int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, c } #endif +static int print_str_common(const mp_print_t *print, const char *str, int prec, size_t len, int flags, int fill, int width) { + if (prec >= 0 && (size_t)prec < len) { + len = prec; + } + return mp_print_strn(print, str, len, flags, fill, width); +} + int mp_printf(const mp_print_t *print, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -484,19 +491,24 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { qstr qst = va_arg(args, qstr); size_t len; const char *str = (const char *)qstr_data(qst, &len); - if (prec >= 0 && (size_t)prec < len) { - len = prec; - } - chrs += mp_print_strn(print, str, len, flags, fill, width); + chrs += print_str_common(print, str, prec, len, flags, fill, width); + break; + } + case 'S': { + compressed_string_t *arg = va_arg(args, compressed_string_t *); + size_t len_with_nul = decompress_length(arg); + size_t len = len_with_nul - 1; + char str[len_with_nul]; + decompress(arg, str); + chrs += print_str_common(print, str, prec, len, flags, fill, width); break; } case 's': { const char *str = va_arg(args, const char *); #ifndef NDEBUG // With debugging enabled, catch printing of null string pointers - if (prec != 0 && str == NULL) { - chrs += mp_print_strn(print, "(null)", 6, flags, fill, width); - break; + if (str == NULL) { + str = "(null)"; } #endif size_t len = strlen(str); @@ -574,3 +586,19 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { } return chrs; } + +int mp_cprintf(const mp_print_t *print, const compressed_string_t *compressed_fmt, ...) { + va_list ap; + va_start(ap, compressed_fmt); + int ret = mp_vcprintf(print, compressed_fmt, ap); + va_end(ap); + return ret; +} + +int mp_vcprintf(const mp_print_t *print, const compressed_string_t *compressed_fmt, va_list args) { + char fmt[decompress_length(compressed_fmt)]; + // TODO: Optimise this to format-while-decompressing (and not require the temp stack space). + decompress(compressed_fmt, fmt); + + return mp_vprintf(print, fmt, args); +} diff --git a/py/mpprint.h b/py/mpprint.h index 4458ea883b..9284935f96 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -71,4 +71,10 @@ int mp_printf(const mp_print_t *print, const char *fmt, ...); int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args); #endif +struct compressed_string; +int mp_cprintf(const mp_print_t *print, const struct compressed_string *compressed_fmt, ...); +#ifdef va_start +int mp_vcprintf(const mp_print_t *print, const struct compressed_string *compressed_fmt, va_list args); +#endif + #endif // MICROPY_INCLUDED_PY_MPPRINT_H diff --git a/py/mpstate.h b/py/mpstate.h index 423463109d..38f1f5188d 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -120,6 +120,9 @@ typedef struct _mp_state_vm_t { qstr_pool_t *last_pool; + // non-heap memory for creating a traceback if we can't allocate RAM + mp_obj_traceback_t mp_emergency_traceback_obj; + // non-heap memory for creating an exception if we can't allocate RAM mp_obj_exception_t mp_emergency_exception_obj; @@ -137,10 +140,14 @@ typedef struct _mp_state_vm_t { #if MICROPY_KBD_EXCEPTION // exception object of type KeyboardInterrupt mp_obj_exception_t mp_kbd_exception; + // traceback object to store traceback + mp_obj_traceback_t mp_kbd_traceback; #endif // exception object of type ReloadException mp_obj_exception_t mp_reload_exception; + // traceback object to store traceback + mp_obj_traceback_t mp_reload_traceback; // dictionary with loaded modules (may be exposed as sys.modules) mp_obj_dict_t mp_loaded_modules_dict; diff --git a/py/obj.c b/py/obj.c index c8a1106a3d..fa3cd0c51c 100644 --- a/py/obj.c +++ b/py/obj.c @@ -143,41 +143,55 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) { } // helper function to print an exception with traceback -void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { +void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit) { if (mp_obj_is_exception_instance(exc) && stack_ok()) { size_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); - // Decompress the format strings - const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n"); - char decompressed[decompress_length(traceback)]; - decompress(traceback, decompressed); #if MICROPY_ENABLE_SOURCE_LINE const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d"); #else const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\""); #endif - char decompressed_frame[decompress_length(frame)]; - decompress(frame, decompressed_frame); const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n"); - char decompressed_block[decompress_length(block_fmt)]; - decompress(block_fmt, decompressed_block); + + // Set traceback formatting + // Default: Print full traceback + limit = limit * 3; + mp_int_t i = n - 3, j; + if (limit > 0) { + // Print upto limit traceback + // entries from caller's frame + if ((unsigned)limit > n) { + limit = n; + } + limit = n - limit; + } else if (limit < 0) { + // Print upto limit traceback + // entries from last + if ((unsigned)-limit > n) { + limit = -n; + } + i = 0, limit = limit + 3; + } // Print the traceback - mp_print_str(print, decompressed); - for (int i = n - 3; i >= 0; i -= 3) { + mp_cprintf(print, MP_ERROR_TEXT("Traceback (most recent call last):\n")); + + for (; i >= limit; i -= 3) { + j = (i < 0) ? -i : i; #if MICROPY_ENABLE_SOURCE_LINE - mp_printf(print, decompressed_frame, values[i], (int)values[i + 1]); + mp_cprintf(print, frame, values[j], (int)values[j + 1]); #else - mp_printf(print, decompressed_frame, values[i]); + mp_cprintf(print, frame, values[j]); #endif - // the block name can be NULL if it's unknown - qstr block = values[i + 2]; + // The block name can be NULL if it's unknown + qstr block = values[j + 2]; if (block == MP_QSTRnull) { mp_print_str(print, "\n"); } else { - mp_printf(print, decompressed_block, block); + mp_cprintf(print, block_fmt, block); } } } @@ -186,6 +200,10 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { mp_print_str(print, "\n"); } +void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { + mp_obj_print_exception_with_limit(print, exc, 0); +} + bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) { if (arg == mp_const_false) { return 0; diff --git a/py/obj.h b/py/obj.h index b259128a2a..a043154ada 100644 --- a/py/obj.h +++ b/py/obj.h @@ -692,6 +692,7 @@ extern const mp_obj_type_t mp_type_bytearray; extern const mp_obj_type_t mp_type_memoryview; extern const mp_obj_type_t mp_type_float; extern const mp_obj_type_t mp_type_complex; +extern const mp_obj_type_t mp_type_traceback; extern const mp_obj_type_t mp_type_tuple; extern const mp_obj_type_t mp_type_list; extern const mp_obj_type_t mp_type_map; // map (the python builtin, not the dict implementation detail) @@ -791,6 +792,7 @@ extern const struct _mp_obj_bool_t mp_const_true_obj; extern const struct _mp_obj_str_t mp_const_empty_bytes_obj; extern const struct _mp_obj_tuple_t mp_const_empty_tuple_obj; extern const struct _mp_obj_dict_t mp_const_empty_dict_obj; +extern const struct _mp_obj_traceback_t mp_const_empty_traceback_obj; extern const struct _mp_obj_singleton_t mp_const_ellipsis_obj; extern const struct _mp_obj_singleton_t mp_const_notimplemented_obj; extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj; @@ -886,6 +888,7 @@ mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc); +void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit); bool mp_obj_is_true(mp_obj_t arg); bool mp_obj_is_callable(mp_obj_t o_in); diff --git a/py/objexcept.c b/py/objexcept.c index d5a858a442..e572225bbc 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -156,7 +156,15 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, con // Populate the exception object o_exc->base.type = type; - o_exc->traceback_data = NULL; + + // Try to allocate memory for the traceback, with fallback to emergency traceback object + o_exc->traceback = m_new_obj_maybe(mp_obj_traceback_t); + if (o_exc->traceback == NULL) { + o_exc->traceback = &MP_STATE_VM(mp_emergency_traceback_obj); + } + + // Populate the traceback object + *o_exc->traceback = mp_const_empty_traceback_obj; mp_obj_tuple_t *o_tuple; if (n_args == 0) { @@ -208,22 +216,25 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] != MP_OBJ_NULL) { // store/delete attribute - if (attr == MP_QSTR___traceback__ && dest[1] == mp_const_none) { - // We allow 'exc.__traceback__ = None' assignment as low-level - // optimization of pre-allocating exception instance and raising - // it repeatedly - this avoids memory allocation during raise. - // However, uPy will keep adding traceback entries to such - // exception instance, so before throwing it, traceback should - // be cleared like above. - self->traceback_len = 0; + if (attr == MP_QSTR___traceback__) { + if (dest[1] == mp_const_none) { + self->traceback->data = NULL; + } else { + if (!mp_obj_is_type(dest[1], &mp_type_traceback)) { + mp_raise_TypeError(MP_ERROR_TEXT("invalid traceback")); + } + self->traceback = MP_OBJ_TO_PTR(dest[1]); + } dest[0] = MP_OBJ_NULL; // indicate success } return; } if (attr == MP_QSTR_args) { dest[0] = MP_OBJ_FROM_PTR(self->args); - } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { + } else if (attr == MP_QSTR_value && self->base.type == &mp_type_StopIteration) { dest[0] = mp_obj_exception_get_value(self_in); + } else if (attr == MP_QSTR___traceback__) { + dest[0] = (self->traceback->data) ? MP_OBJ_FROM_PTR(self->traceback) : mp_const_none; #if MICROPY_CPYTHON_COMPAT } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { if (attr == MP_QSTR_errno) { @@ -454,12 +465,9 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com o_str->data = NULL; } else { // We have some memory to format the string. - // TODO: Optimise this to format-while-decompressing (and not require the temp stack space). struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf}; mp_print_t print = {&exc_pr, exc_add_strn}; - char fmt_decompressed[decompress_length(fmt)]; - decompress(fmt, fmt_decompressed); - mp_vprintf(&print, fmt_decompressed, ap); + mp_vcprintf(&print, fmt, ap); exc_pr.buf[exc_pr.len] = '\0'; o_str->len = exc_pr.len; o_str->data = exc_pr.buf; @@ -552,7 +560,7 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in) { GET_NATIVE_EXCEPTION(self, self_in); // just set the traceback to the null object // we don't want to call any memory management functions here - self->traceback_data = NULL; + self->traceback->data = NULL; } void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) { @@ -561,16 +569,16 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs // append this traceback info to traceback data // if memory allocation fails (eg because gc is locked), just return - if (self->traceback_data == NULL) { - self->traceback_data = m_new_maybe(size_t, TRACEBACK_ENTRY_LEN); - if (self->traceback_data == NULL) { + if (self->traceback->data == NULL) { + self->traceback->data = m_new_maybe(size_t, TRACEBACK_ENTRY_LEN); + if (self->traceback->data == NULL) { #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF if (mp_emergency_exception_buf_size >= (mp_int_t)(EMG_BUF_TRACEBACK_OFFSET + EMG_BUF_TRACEBACK_SIZE)) { // There is room in the emergency buffer for traceback data size_t *tb = (size_t *)((uint8_t *)MP_STATE_VM(mp_emergency_exception_buf) + EMG_BUF_TRACEBACK_OFFSET); - self->traceback_data = tb; - self->traceback_alloc = EMG_BUF_TRACEBACK_SIZE / sizeof(size_t); + self->traceback->data = tb; + self->traceback->alloc = EMG_BUF_TRACEBACK_SIZE / sizeof(size_t); } else { // Can't allocate and no room in emergency buffer return; @@ -581,28 +589,28 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs #endif } else { // Allocated the traceback data on the heap - self->traceback_alloc = TRACEBACK_ENTRY_LEN; + self->traceback->alloc = TRACEBACK_ENTRY_LEN; } - self->traceback_len = 0; - } else if (self->traceback_len + TRACEBACK_ENTRY_LEN > self->traceback_alloc) { + self->traceback->len = 0; + } else if (self->traceback->len + TRACEBACK_ENTRY_LEN > self->traceback->alloc) { #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF - if (self->traceback_data == (size_t *)MP_STATE_VM(mp_emergency_exception_buf)) { + if (self->traceback->data == (size_t *)MP_STATE_VM(mp_emergency_exception_buf)) { // Can't resize the emergency buffer return; } #endif // be conservative with growing traceback data - size_t *tb_data = m_renew_maybe(size_t, self->traceback_data, self->traceback_alloc, - self->traceback_alloc + TRACEBACK_ENTRY_LEN, true); + size_t *tb_data = m_renew_maybe(size_t, self->traceback->data, self->traceback->alloc, + self->traceback->alloc + TRACEBACK_ENTRY_LEN, true); if (tb_data == NULL) { return; } - self->traceback_data = tb_data; - self->traceback_alloc += TRACEBACK_ENTRY_LEN; + self->traceback->data = tb_data; + self->traceback->alloc += TRACEBACK_ENTRY_LEN; } - size_t *tb_data = &self->traceback_data[self->traceback_len]; - self->traceback_len += TRACEBACK_ENTRY_LEN; + size_t *tb_data = &self->traceback->data[self->traceback->len]; + self->traceback->len += TRACEBACK_ENTRY_LEN; tb_data[0] = file; tb_data[1] = line; tb_data[2] = block; @@ -611,12 +619,12 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values) { GET_NATIVE_EXCEPTION(self, self_in); - if (self->traceback_data == NULL) { + if (self->traceback->data == NULL) { *n = 0; *values = NULL; } else { - *n = self->traceback_len; - *values = self->traceback_data; + *n = self->traceback->len; + *values = self->traceback->data; } } diff --git a/py/objexcept.h b/py/objexcept.h index d7b39add87..261885e54d 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -28,13 +28,12 @@ #include "py/obj.h" #include "py/objtuple.h" +#include "py/objtraceback.h" typedef struct _mp_obj_exception_t { mp_obj_base_t base; - size_t traceback_alloc : (8 * sizeof(size_t) / 2); - size_t traceback_len : (8 * sizeof(size_t) / 2); - size_t *traceback_data; mp_obj_tuple_t *args; + mp_obj_traceback_t *traceback; } mp_obj_exception_t; void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); diff --git a/py/objgenerator.c b/py/objgenerator.c index 2139e4478a..7bafd9ce98 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -38,7 +38,7 @@ #include "supervisor/shared/translate.h" // Instance of GeneratorExit exception - needed by generator.close() -const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, 0, 0, NULL, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj}; +const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; /******************************************************************************/ /* generator wrapper */ diff --git a/py/objmodule.c b/py/objmodule.c index 8fa36ab42e..ea10fb8ba2 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -161,9 +161,6 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { { MP_ROM_QSTR(MP_QSTR_builtins), MP_ROM_PTR(&mp_module_builtins) }, { MP_ROM_QSTR(MP_QSTR_micropython), MP_ROM_PTR(&mp_module_micropython) }, - #if MICROPY_PY_ARRAY - { MP_ROM_QSTR(MP_QSTR_array), MP_ROM_PTR(&mp_module_array) }, - #endif #if MICROPY_PY_IO #if CIRCUITPY { MP_ROM_QSTR(MP_QSTR_io), MP_ROM_PTR(&mp_module_io) }, diff --git a/py/objtraceback.c b/py/objtraceback.c new file mode 100644 index 0000000000..f1f74142d6 --- /dev/null +++ b/py/objtraceback.c @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/runtime.h" +#include "py/objtraceback.h" + +const mp_obj_traceback_t mp_const_empty_traceback_obj = {{&mp_type_traceback}, 0, 0, NULL}; + +STATIC void mp_obj_traceback_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { + (void)kind; + mp_obj_traceback_t *o = MP_OBJ_TO_PTR(o_in); + mp_printf(print, "", o); +} + +const mp_obj_type_t mp_type_traceback = { + { &mp_type_type }, + .name = MP_QSTR_traceback, + .print = mp_obj_traceback_print, +}; diff --git a/shared-module/busio/OneWire.h b/py/objtraceback.h similarity index 76% rename from shared-module/busio/OneWire.h rename to py/objtraceback.h index 5d80bab17c..992fe89b01 100644 --- a/shared-module/busio/OneWire.h +++ b/py/objtraceback.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 microDev * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,16 +24,16 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H - -#include "shared-module/bitbangio/OneWire.h" +#ifndef MICROPY_INCLUDED_PY_OBJTRACEBACK_H +#define MICROPY_INCLUDED_PY_OBJTRACEBACK_H #include "py/obj.h" -typedef struct { +typedef struct _mp_obj_traceback_t { mp_obj_base_t base; - bitbangio_onewire_obj_t bitbang; -} busio_onewire_obj_t; + size_t alloc : (8 * sizeof(size_t) / 2); + size_t len : (8 * sizeof(size_t) / 2); + size_t *data; +} mp_obj_traceback_t; -#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H +#endif // MICROPY_INCLUDED_PY_OBJTRACEBACK_H diff --git a/py/py.cmake b/py/py.cmake index 2b5d437b57..6f0514e0e3 100644 --- a/py/py.cmake +++ b/py/py.cmake @@ -95,6 +95,7 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/objstr.c ${MICROPY_PY_DIR}/objstringio.c ${MICROPY_PY_DIR}/objstrunicode.c + ${MICROPY_PY_DIR}/objtraceback.c ${MICROPY_PY_DIR}/objtuple.c ${MICROPY_PY_DIR}/objtype.c ${MICROPY_PY_DIR}/objzip.c diff --git a/py/py.mk b/py/py.mk index 94ac82f6f0..7c3eaf4f46 100644 --- a/py/py.mk +++ b/py/py.mk @@ -153,6 +153,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ objstr.o \ objstrunicode.o \ objstringio.o \ + objtraceback.o \ objtuple.o \ objtype.o \ objzip.o \ diff --git a/py/runtime.c b/py/runtime.c index ceb5e83b14..55f26021ab 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -79,17 +79,15 @@ void mp_init(void) { #if MICROPY_KBD_EXCEPTION // initialise the exception object for raising KeyboardInterrupt MP_STATE_VM(mp_kbd_exception).base.type = &mp_type_KeyboardInterrupt; - MP_STATE_VM(mp_kbd_exception).traceback_alloc = 0; - MP_STATE_VM(mp_kbd_exception).traceback_len = 0; - MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; + MP_STATE_VM(mp_kbd_exception).traceback = &MP_STATE_VM(mp_kbd_traceback); + *MP_STATE_VM(mp_kbd_exception).traceback = mp_const_empty_traceback_obj; #endif MP_STATE_VM(mp_reload_exception).base.type = &mp_type_ReloadException; - MP_STATE_VM(mp_reload_exception).traceback_alloc = 0; - MP_STATE_VM(mp_reload_exception).traceback_len = 0; - MP_STATE_VM(mp_reload_exception).traceback_data = NULL; MP_STATE_VM(mp_reload_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; + MP_STATE_VM(mp_reload_exception).traceback = &MP_STATE_VM(mp_reload_traceback); + *MP_STATE_VM(mp_reload_exception).traceback = mp_const_empty_traceback_obj; // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC diff --git a/py/scheduler.c b/py/scheduler.c index f11317dc1d..733722e46a 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -40,7 +40,7 @@ void MICROPY_WRAP_MP_SCHED_EXCEPTION(mp_sched_exception)(mp_obj_t exc) { #if MICROPY_KBD_EXCEPTION // This function may be called asynchronously at any time so only do the bare minimum. void MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(mp_sched_keyboard_interrupt)(void) { - MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; + MP_STATE_VM(mp_kbd_exception).traceback->data = NULL; mp_sched_exception(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); } #endif diff --git a/requirements-dev.txt b/requirements-dev.txt index 1fb88552fe..c3b33f8713 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,6 +7,7 @@ jinja2 typer requests +requests-cache sh click setuptools @@ -16,7 +17,7 @@ cpp-coveralls Sphinx<4 sphinx-rtd-theme myst-parser -sphinx-autoapi<=1.8.1 +sphinx-autoapi sphinxcontrib-svg2pdfconverter readthedocs-sphinx-search diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index 8262830aee..c126ee79f2 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -197,10 +197,10 @@ const mp_obj_property_t bleio_adapter_name_obj = { //| """Starts advertising until `stop_advertising` is called or if connectable, another device //| connects to us. //| -//| .. warning: If data is longer than 31 bytes, then this will automatically advertise as an +//| .. warning:: If data is longer than 31 bytes, then this will automatically advertise as an //| extended advertisement that older BLE 4.x clients won't be able to scan for. //| -//| .. note: If you set ``anonymous=True``, then a timeout must be specified. If no timeout is +//| .. note:: If you set ``anonymous=True``, then a timeout must be specified. If no timeout is //| specified, then the maximum allowed timeout will be selected automatically. //| //| :param ~_typing.ReadableBuffer data: advertising data packet bytes diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c deleted file mode 100644 index 15cf833242..0000000000 --- a/shared-bindings/bitbangio/OneWire.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of the Micro Python 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 - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/runtime0.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/bitbangio/OneWire.h" -#include "shared-bindings/util.h" - -//| class OneWire: -//| """Lowest-level of the Maxim OneWire protocol -//| -//| :class:`~bitbangio.OneWire` implements the timing-sensitive foundation of -//| the Maxim (formerly Dallas Semi) OneWire protocol. -//| -//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126""" -//| -//| def __init__(self, pin: microcontroller.Pin) -> None: -//| -//| """Create a OneWire object associated with the given pin. The object -//| implements the lowest level timing-sensitive bits of the protocol. -//| -//| :param ~microcontroller.Pin pin: Pin to read pulses from. -//| -//| Read a short series of pulses:: -//| -//| import bitbangio -//| import board -//| -//| onewire = bitbangio.OneWire(board.D7) -//| onewire.reset() -//| onewire.write_bit(True) -//| onewire.write_bit(False) -//| print(onewire.read_bit())""" -//| ... -//| -STATIC mp_obj_t bitbangio_onewire_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_pin }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); - - bitbangio_onewire_obj_t *self = m_new_obj(bitbangio_onewire_obj_t); - self->base.type = &bitbangio_onewire_type; - - shared_module_bitbangio_onewire_construct(self, pin); - return MP_OBJ_FROM_PTR(self); -} - -//| def deinit(self) -> None: -//| """Deinitialize the OneWire bus and release any hardware resources for reuse.""" -//| ... -//| -STATIC mp_obj_t bitbangio_onewire_deinit(mp_obj_t self_in) { - bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - shared_module_bitbangio_onewire_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire_deinit); - -STATIC void check_for_deinit(bitbangio_onewire_obj_t *self) { - if (shared_module_bitbangio_onewire_deinited(self)) { - raise_deinited_error(); - } -} - -//| def __enter__(self) -> OneWire: -//| """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 bitbangio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - shared_module_bitbangio_onewire_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4, bitbangio_onewire_obj___exit__); - -//| def reset(self) -> bool: -//| """Reset the OneWire bus""" -//| ... -//| -STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) { - bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - - return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_reset); - -//| def read_bit(self) -> bool: -//| """Read in a bit -//| -//| :returns: bit state read -//| :rtype: bool""" -//| ... -//| -STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) { - bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - - return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_read_bit); - -//| def write_bit(self, value: bool) -> None: -//| """Write out a bit based on value.""" -//| ... -//| -STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { - bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - - shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_onewire_write_bit_obj, bitbangio_onewire_obj_write_bit); - -STATIC const mp_rom_map_elem_t bitbangio_onewire_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_onewire_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_onewire___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&bitbangio_onewire_reset_obj) }, - { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&bitbangio_onewire_read_bit_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&bitbangio_onewire_write_bit_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(bitbangio_onewire_locals_dict, bitbangio_onewire_locals_dict_table); - -const mp_obj_type_t bitbangio_onewire_type = { - { &mp_type_type }, - .name = MP_QSTR_OneWire, - .make_new = bitbangio_onewire_make_new, - .locals_dict = (mp_obj_dict_t *)&bitbangio_onewire_locals_dict, -}; diff --git a/shared-bindings/bitbangio/__init__.c b/shared-bindings/bitbangio/__init__.c index 81e9d91a37..a8d9f5e615 100644 --- a/shared-bindings/bitbangio/__init__.c +++ b/shared-bindings/bitbangio/__init__.c @@ -34,7 +34,7 @@ #include "shared-bindings/bitbangio/__init__.h" #include "shared-bindings/bitbangio/I2C.h" -#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/onewireio/OneWire.h" #include "shared-bindings/bitbangio/SPI.h" #include "py/runtime.h" @@ -72,7 +72,7 @@ STATIC const mp_rom_map_elem_t bitbangio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitbangio) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&bitbangio_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&bitbangio_onewire_type) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&onewireio_onewire_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&bitbangio_spi_type) }, }; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 31f3a9021e..a611d8e1d5 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -104,7 +104,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con common_hal_busio_spi_construct(self, clock, mosi, miso); return MP_OBJ_FROM_PTR(self); #else - mp_raise_NotImplementedError(NULL); + mp_raise_ValueError(translate("Invalid pins")); #endif // CIRCUITPY_BUSIO_SPI } diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 67ca752bab..f4737da0c0 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -52,7 +52,7 @@ extern void common_hal_busio_spi_unlock(busio_spi_obj_t *self); // Writes out the given data. extern bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len); -// Reads in len bytes while outputting zeroes. +// Reads in len bytes while outputting the byte write_value. extern bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value); // Reads and write len bytes simultaneously. diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index bd97910192..efb0643d0b 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -72,13 +72,16 @@ typedef struct { extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; +#if CIRCUITPY_BUSIO_UART STATIC void validate_timeout(mp_float_t timeout) { if (timeout < (mp_float_t)0.0f || timeout > (mp_float_t)100.0f) { mp_raise_ValueError(translate("timeout must be 0.0-100.0 seconds")); } } +#endif // CIRCUITPY_BUSIO_UART STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CIRCUITPY_BUSIO_UART // Always initially allocate the UART object within the long-lived heap. // This is needed to avoid crashes with certain UART implementations which // cannot accomodate being moved after creation. (See @@ -141,8 +144,12 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co args[ARG_baudrate].u_int, bits, parity, stop, timeout, args[ARG_receiver_buffer_size].u_int, NULL, false); return (mp_obj_t)self; + #else + mp_raise_ValueError(translate("Invalid pins")); + #endif // CIRCUITPY_BUSIO_UART } +#if CIRCUITPY_BUSIO_UART // Helper to ensure we have the native super class instead of a subclass. busio_uart_obj_t *native_uart(mp_obj_t uart_obj) { @@ -358,6 +365,7 @@ STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); +#endif // CIRCUITPY_BUSIO_UART //| class Parity: //| """Enum-like class to define the parity used to verify correct data transfer.""" @@ -400,6 +408,7 @@ const mp_obj_type_t busio_uart_parity_type = { }; STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { + #if CIRCUITPY_BUSIO_UART { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, @@ -417,12 +426,14 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) }, { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&busio_uart_timeout_obj) }, + #endif // CIRCUITPY_BUSIO_UART // Nested Enum-like Classes. { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) }, }; STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table); +#if CIRCUITPY_BUSIO_UART STATIC const mp_stream_p_t uart_stream_p = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) .read = busio_uart_read, @@ -445,3 +456,11 @@ const mp_obj_type_t busio_uart_type = { .protocol = &uart_stream_p, ), }; +#else +const mp_obj_type_t busio_uart_type = { + { &mp_type_type }, + .name = MP_QSTR_UART, + .make_new = busio_uart_make_new, + .locals_dict = (mp_obj_dict_t *)&busio_uart_locals_dict, +}; +#endif // CIRCUITPY_BUSIO_UART diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c index e7df331c12..2cde3d62b3 100644 --- a/shared-bindings/busio/__init__.c +++ b/shared-bindings/busio/__init__.c @@ -32,9 +32,9 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/__init__.h" #include "shared-bindings/busio/I2C.h" -#include "shared-bindings/busio/OneWire.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/busio/UART.h" +#include "shared-bindings/onewireio/OneWire.h" #include "py/runtime.h" @@ -73,7 +73,7 @@ STATIC const mp_rom_map_elem_t busio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_busio) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&busio_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&busio_spi_type) }, - { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&busio_onewire_type) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&onewireio_onewire_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&busio_uart_type) }, }; diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index d9863e8a21..7f367ee791 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -80,7 +80,7 @@ MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); //| ERROR_WARNING: object //| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. //| -//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" +//| .. note:: Not all implementations may use ``ERROR_WARNING``. Do not rely on seeing ``ERROR_WARNING`` before ``ERROR_PASSIVE``.""" //| //| ERROR_PASSIVE: object //| """The bus is in the passive state due to the number of errors that have occurred recently. diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index e12e398802..f5df146455 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -230,14 +230,14 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) } MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); -//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 1) -> bool: +//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 0) -> bool: //| """When auto refresh is off, waits for the target frame rate and then refreshes the display, //| returning True. If the call has taken too long since the last refresh call for the given //| target frame rate, then the refresh returns False immediately without updating the screen to //| hopefully help getting caught up. //| //| If the time since the last successful refresh is below the minimum frame rate, then an -//| exception will be raised. Set ``minimum_frames_per_second`` to 0 to disable. +//| exception will be raised. The default ``minimum_frames_per_second`` of 0 disables this behavior. //| //| When auto refresh is off, ``display.refresh()`` or ``display.refresh(target_frames_per_second=None)`` //| will update the display immediately. @@ -254,7 +254,7 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index e80b243223..0f62ae63b4 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -54,7 +54,9 @@ //| width: int, height: int, ram_width: int, ram_height: int, //| colstart: int = 0, rowstart: int = 0, rotation: int = 0, //| set_column_window_command: Optional[int] = None, -//| set_row_window_command: Optional[int] = None, single_byte_bounds: bool = False, +//| set_row_window_command: Optional[int] = None, +//| set_current_column_command: Optional[int] = None, +//| set_current_row_command: Optional[int] = None, //| write_black_ram_command: int, black_bits_inverted: bool = False, //| write_color_ram_command: Optional[int] = None, //| color_bits_inverted: bool = False, highlight_color: int = 0x000000, diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index d636ee335b..4783c97453 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -183,7 +183,7 @@ const mp_obj_property_t displayio_group_y_obj = { MP_ROM_NONE}, }; -//| def append(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def append(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Append a layer to the group. It will be drawn above other layers.""" //| ... //| @@ -194,7 +194,7 @@ STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append); -//| def insert(self, index: int, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def insert(self, index: int, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Insert a layer into the group.""" //| ... //| @@ -210,7 +210,7 @@ STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert); -//| def index(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> int: +//| def index(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> int: //| """Returns the index of the first copy of layer. Raises ValueError if not found.""" //| ... //| @@ -224,7 +224,7 @@ STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index); -//| def pop(self, i: int = -1) -> Union[vectorio.VectorShape, Group, TileGrid]: +//| def pop(self, i: int = -1) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Remove the ith item and return it.""" //| ... //| @@ -247,7 +247,7 @@ STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop); -//| def remove(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def remove(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Remove the first copy of layer. Raises ValueError if it is not present.""" //| ... //| @@ -280,7 +280,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } } -//| def __getitem__(self, index: int) -> Union[vectorio.VectorShape, Group, TileGrid]: +//| def __getitem__(self, index: int) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Returns the value at the given index. //| //| This allows you to:: @@ -288,7 +288,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| print(group[0])""" //| ... //| -//| def __setitem__(self, index: int, value: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def __setitem__(self, index: int, value: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Sets the value at the given index. //| //| This allows you to:: diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c new file mode 100644 index 0000000000..d627087aae --- /dev/null +++ b/shared-bindings/getpass/__init__.c @@ -0,0 +1,86 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * 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/stream.h" +#include "shared-module/getpass/__init__.h" + +//| """Getpass Module +//| +//| This module provides a way to get input from user without echoing it. +//| +//| """ +//| ... +//| + +//| def getpass(prompt: Optional[str] = 'Password: ', stream: Optional[io.FileIO] = None) -> str: +//| +//| """Prompt the user without echoing. +//| +//| :param str prompt: The user is prompted using the string ``prompt``, which defaults to ``'Password: '``. +//| :param io.FileIO stream: The ``prompt`` is written to the file-like object ``stream`` if provided. +//| +//| """ +//| ... +//| +STATIC mp_obj_t getpass_getpass(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_prompt, ARG_stream }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_prompt, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_stream, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const char *prompt = (args[ARG_prompt].u_obj == mp_const_none) ? "Password: " : mp_obj_str_get_str(args[ARG_prompt].u_obj); + + mp_print_t print = {.data = NULL}; + if (args[ARG_stream].u_obj != mp_const_none) { + #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES + mp_get_stream_raise(args[ARG_stream].u_obj, MP_STREAM_OP_WRITE); + print.data = MP_OBJ_TO_PTR(args[ARG_stream].u_obj); + print.print_strn = mp_stream_write_adaptor; + #else + mp_raise_NotImplementedError(translate("stream operation not supported")); + #endif + } + + return shared_module_getpass_getpass(prompt, ((print.data) ? &print : NULL)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(getpass_getpass_obj, 0, getpass_getpass); + +STATIC const mp_rom_map_elem_t getpass_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_getpass) }, + // module functions + { MP_ROM_QSTR(MP_QSTR_getpass), MP_ROM_PTR(&getpass_getpass_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(getpass_module_globals, getpass_module_globals_table); + +const mp_obj_module_t getpass_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&getpass_module_globals, +}; diff --git a/shared-bindings/keypad/EventQueue.c b/shared-bindings/keypad/EventQueue.c index 15cc027b8c..2cb449551b 100644 --- a/shared-bindings/keypad/EventQueue.c +++ b/shared-bindings/keypad/EventQueue.c @@ -68,7 +68,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_obj, keypad_eventqueue_get); //| Note that the queue size is limited; see ``max_events`` in the constructor of //| a scanner such as `Keys` or `KeyMatrix`. //| -//| :return ``True`` if an event was available and stored, ``False`` if not. +//| :return: ``True`` if an event was available and stored, ``False`` if not. //| :rtype: bool //| """ //| ... diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index 0b854ef475..dbb4ac6822 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -90,6 +90,8 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar mcu_pin_obj_t *row_pins_array[num_row_pins]; mcu_pin_obj_t *column_pins_array[num_column_pins]; + validate_no_duplicate_pins_2(row_pins, column_pins, MP_QSTR_row_pins, MP_QSTR_column_pins); + for (size_t row = 0; row < num_row_pins; row++) { mcu_pin_obj_t *pin = validate_obj_is_free_pin(mp_obj_subscr(row_pins, MP_OBJ_NEW_SMALL_INT(row), MP_OBJ_SENTINEL)); diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index d616bcff84..dc533a2e2b 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -78,6 +78,7 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, c mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t pins = args[ARG_pins].u_obj; + validate_no_duplicate_pins(pins, MP_QSTR_row_pins); // mp_obj_len() will be >= 0. const size_t num_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(pins)); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index acb1710f3d..78c1c90f4d 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -105,6 +105,45 @@ mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj) { return pin; } +// Validate every element in the list is a unique pin +void validate_no_duplicate_pins(mp_obj_t seq, qstr arg_name) { + const size_t num_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); + + for (size_t pin_cnt = 0; pin_cnt < num_pins; pin_cnt++) { + mp_obj_t pin1_obj = mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(pin_cnt), MP_OBJ_SENTINEL); + mcu_pin_obj_t *pin1 = validate_obj_is_pin(pin1_obj); + + for (size_t pin_cnt_2 = pin_cnt + 1; pin_cnt_2 < num_pins; pin_cnt_2++) { + mp_obj_t pin2_obj = mp_obj_subscr(seq, MP_OBJ_NEW_SMALL_INT(pin_cnt_2), MP_OBJ_SENTINEL); + mcu_pin_obj_t *pin2 = validate_obj_is_pin(pin2_obj); + if (pin1 == pin2) { + mp_raise_TypeError_varg(translate("%q contains duplicate pins"), arg_name); + } + } + } +} + +void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, qstr arg_name2) { + const size_t num_pins_1 = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq1)); + const size_t num_pins_2 = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq2)); + + validate_no_duplicate_pins(seq1, arg_name1); + validate_no_duplicate_pins(seq2, arg_name2); + + for (size_t pin_cnt_1 = 0; pin_cnt_1 < num_pins_1; pin_cnt_1++) { + mp_obj_t pin1_obj = mp_obj_subscr(seq1, MP_OBJ_NEW_SMALL_INT(pin_cnt_1), MP_OBJ_SENTINEL); + mcu_pin_obj_t *pin1 = validate_obj_is_pin(pin1_obj); + + for (size_t pin_cnt_2 = 0; pin_cnt_2 < num_pins_2; pin_cnt_2++) { + mp_obj_t pin2_obj = mp_obj_subscr(seq2, MP_OBJ_NEW_SMALL_INT(pin_cnt_2), MP_OBJ_SENTINEL); + mcu_pin_obj_t *pin2 = validate_obj_is_pin(pin2_obj); + if (pin1 == pin2) { + mp_raise_TypeError_varg(translate("%q and %q contain duplicate pins"), arg_name1, arg_name2); + } + } + } +} + // Validate every element in the list to be a free pin. void validate_list_is_free_pins(qstr what, mcu_pin_obj_t **pins_out, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out) { mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 44019ff267..a8ac6eeb1c 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -37,6 +37,8 @@ mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj); mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj); mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj); mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj); +void validate_no_duplicate_pins(mp_obj_t seq, qstr arg_name); +void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, qstr arg_name2); void validate_list_is_free_pins(qstr what, mcu_pin_obj_t **pins_out, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out); void validate_pins(qstr what, uint8_t *pin_nos, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out); diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/onewireio/OneWire.c similarity index 54% rename from shared-bindings/busio/OneWire.c rename to shared-bindings/onewireio/OneWire.c index 026e1ee968..406b421fd1 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -31,37 +31,33 @@ #include "py/runtime.h" #include "py/runtime0.h" #include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/busio/OneWire.h" +#include "shared-bindings/onewireio/OneWire.h" #include "shared-bindings/util.h" //| class OneWire: -//| """Lowest-level of the Maxim OneWire protocol""" -//| //| def __init__(self, pin: microcontroller.Pin) -> None: -//| """(formerly Dallas Semi) OneWire protocol. +//| """Create a OneWire object associated with the given pin. //| -//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 -//| -//| .. class:: OneWire(pin) -//| -//| Create a OneWire object associated with the given pin. The object -//| implements the lowest level timing-sensitive bits of the protocol. +//| The object implements the lowest level timing-sensitive bits of the protocol. //| //| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus //| +//| .. note:: The OneWire class is available on `busio` and `bitbangio` in CircuitPython +//| 7.x for backwards compatibility but will be removed in CircuitPython 8.0.0. +//| //| Read a short series of pulses:: //| -//| import busio +//| import onewireio //| import board //| -//| onewire = busio.OneWire(board.D7) +//| onewire = onewireio.OneWire(board.D7) //| onewire.reset() //| onewire.write_bit(True) //| onewire.write_bit(False) //| print(onewire.read_bit())""" //| ... //| -STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t onewireio_onewire_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_pin }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -70,10 +66,10 @@ STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); - busio_onewire_obj_t *self = m_new_obj(busio_onewire_obj_t); - self->base.type = &busio_onewire_type; + onewireio_onewire_obj_t *self = m_new_obj(onewireio_onewire_obj_t); + self->base.type = &onewireio_onewire_type; - common_hal_busio_onewire_construct(self, pin); + common_hal_onewireio_onewire_construct(self, pin); return MP_OBJ_FROM_PTR(self); } @@ -81,15 +77,15 @@ STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, //| """Deinitialize the OneWire bus and release any hardware resources for reuse.""" //| ... //| -STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) { - busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_busio_onewire_deinit(self); +STATIC mp_obj_t onewireio_onewire_deinit(mp_obj_t self_in) { + onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_onewireio_onewire_deinit(self); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_deinit_obj, onewireio_onewire_deinit); -STATIC void check_for_deinit(busio_onewire_obj_t *self) { - if (common_hal_busio_onewire_deinited(self)) { +STATIC void check_for_deinit(onewireio_onewire_obj_t *self) { + if (common_hal_onewireio_onewire_deinited(self)) { raise_deinited_error(); } } @@ -105,12 +101,12 @@ STATIC void check_for_deinit(busio_onewire_obj_t *self) { //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... //| -STATIC mp_obj_t busio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t onewireio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; - common_hal_busio_onewire_deinit(args[0]); + common_hal_onewireio_onewire_deinit(args[0]); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, busio_onewire_obj___exit__); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(onewireio_onewire___exit___obj, 4, 4, onewireio_onewire_obj___exit__); //| def reset(self) -> bool: //| """Reset the OneWire bus and read presence @@ -119,13 +115,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, bus //| :rtype: bool""" //| ... //| -STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) { - busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t onewireio_onewire_obj_reset(mp_obj_t self_in) { + onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return mp_obj_new_bool(common_hal_busio_onewire_reset(self)); + return mp_obj_new_bool(common_hal_onewireio_onewire_reset(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); +MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_reset_obj, onewireio_onewire_obj_reset); //| def read_bit(self) -> bool: //| """Read in a bit @@ -134,41 +130,41 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); //| :rtype: bool""" //| ... //| -STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) { - busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t onewireio_onewire_obj_read_bit(mp_obj_t self_in) { + onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self)); + return mp_obj_new_bool(common_hal_onewireio_onewire_read_bit(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit); +MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_read_bit_obj, onewireio_onewire_obj_read_bit); //| def write_bit(self, value: bool) -> None: //| """Write out a bit based on value.""" //| ... //| -STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { - busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t onewireio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { + onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); + common_hal_onewireio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(busio_onewire_write_bit_obj, busio_onewire_obj_write_bit); +MP_DEFINE_CONST_FUN_OBJ_2(onewireio_onewire_write_bit_obj, onewireio_onewire_obj_write_bit); -STATIC const mp_rom_map_elem_t busio_onewire_locals_dict_table[] = { +STATIC const mp_rom_map_elem_t onewireio_onewire_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_onewire_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&onewireio_onewire_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_onewire___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&busio_onewire_reset_obj) }, - { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&busio_onewire_read_bit_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&busio_onewire_write_bit_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&onewireio_onewire___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&onewireio_onewire_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&onewireio_onewire_read_bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&onewireio_onewire_write_bit_obj) }, }; -STATIC MP_DEFINE_CONST_DICT(busio_onewire_locals_dict, busio_onewire_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(onewireio_onewire_locals_dict, onewireio_onewire_locals_dict_table); -const mp_obj_type_t busio_onewire_type = { +const mp_obj_type_t onewireio_onewire_type = { { &mp_type_type }, .name = MP_QSTR_OneWire, - .make_new = busio_onewire_make_new, - .locals_dict = (mp_obj_dict_t *)&busio_onewire_locals_dict, + .make_new = onewireio_onewire_make_new, + .locals_dict = (mp_obj_dict_t *)&onewireio_onewire_locals_dict, }; diff --git a/shared-bindings/bitbangio/OneWire.h b/shared-bindings/onewireio/OneWire.h similarity index 63% rename from shared-bindings/bitbangio/OneWire.h rename to shared-bindings/onewireio/OneWire.h index 0dbc975122..c6d0fd6ebb 100644 --- a/shared-bindings/bitbangio/OneWire.h +++ b/shared-bindings/onewireio/OneWire.h @@ -24,20 +24,20 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO_ONEWIRE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO_ONEWIRE_H #include "common-hal/microcontroller/Pin.h" -#include "shared-module/bitbangio/OneWire.h" +#include "shared-module/onewireio/OneWire.h" -extern const mp_obj_type_t bitbangio_onewire_type; +extern const mp_obj_type_t onewireio_onewire_type; -extern void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t *self, +extern void common_hal_onewireio_onewire_construct(onewireio_onewire_obj_t *self, const mcu_pin_obj_t *pin); -extern void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t *self); -extern bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t *self); -extern bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t *self); -extern bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t *self); -extern void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t *self, bool bit); +extern void common_hal_onewireio_onewire_deinit(onewireio_onewire_obj_t *self); +extern bool common_hal_onewireio_onewire_deinited(onewireio_onewire_obj_t *self); +extern bool common_hal_onewireio_onewire_reset(onewireio_onewire_obj_t *self); +extern bool common_hal_onewireio_onewire_read_bit(onewireio_onewire_obj_t *self); +extern void common_hal_onewireio_onewire_write_bit(onewireio_onewire_obj_t *self, bool bit); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO_ONEWIRE_H diff --git a/shared-bindings/onewireio/__init__.c b/shared-bindings/onewireio/__init__.c new file mode 100644 index 0000000000..81baa99fab --- /dev/null +++ b/shared-bindings/onewireio/__init__.c @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/onewireio/__init__.h" +#include "shared-bindings/onewireio/OneWire.h" + +#include "py/runtime.h" + +//| """Low-level bit primitives for Maxim (formerly Dallas Semi) one-wire protocol. +//| +//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126""" +//| + +STATIC const mp_rom_map_elem_t onewireio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewireio) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&onewireio_onewire_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(onewireio_module_globals, onewireio_module_globals_table); + +const mp_obj_module_t onewireio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&onewireio_module_globals, +}; diff --git a/ports/nrf/common-hal/busio/OneWire.h b/shared-bindings/onewireio/__init__.h similarity index 84% rename from ports/nrf/common-hal/busio/OneWire.h rename to shared-bindings/onewireio/__init__.h index 821cc64c1e..25384f6a7b 100644 --- a/ports/nrf/common-hal/busio/OneWire.h +++ b/shared-bindings/onewireio/__init__.h @@ -24,10 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO___INIT___H -// Use bitbangio. -#include "shared-module/busio/OneWire.h" +#include "py/obj.h" -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BUSIO_ONEWIRE_H +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ONEWIREIO___INIT___H diff --git a/shared-bindings/qrio/PixelPolicy.c b/shared-bindings/qrio/PixelPolicy.c new file mode 100644 index 0000000000..6887081b24 --- /dev/null +++ b/shared-bindings/qrio/PixelPolicy.c @@ -0,0 +1,56 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/qrio/__init__.h" +#include "shared-bindings/qrio/PixelPolicy.h" +#include "py/obj.h" +#include "py/enum.h" + +//| class PixelPolicy: +//| EVERY_BYTE: PixelPolicy +//| """The input buffer to `QRDecoder.decode` consists of greyscale values in every byte""" +//| +//| EVEN_BYTES: PixelPolicy +//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 0, 2, …, and ignored bytes in positions 1, 3, …. This can decode directly from YUV images where the even bytes hold the Y (luminance) data.""" +//| +//| ODD_BYTES: PixelPolicy +//| """The input buffer to `QRDecoder.decode` consists of greyscale values in positions 1, 3, …, and ignored bytes in positions 0, 2, …. This can decode directly from YUV images where the odd bytes hold the Y (luminance) data""" +//| + +MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, EVERY_BYTE, QRIO_EVERY_BYTE); +MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, EVEN_BYTES, QRIO_EVEN_BYTES); +MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, ODD_BYTES, QRIO_EVEN_BYTES); + +MAKE_ENUM_MAP(qrio_pixel_policy) { + MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, EVERY_BYTE), + MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, EVEN_BYTES), + MAKE_ENUM_MAP_ENTRY(qrio_pixel_policy, ODD_BYTES), +}; +STATIC MP_DEFINE_CONST_DICT(qrio_pixel_policy_locals_dict, qrio_pixel_policy_locals_table); + +MAKE_PRINTER(qrio, qrio_pixel_policy); + +MAKE_ENUM_TYPE(qrio, PixelPolicy, qrio_pixel_policy); diff --git a/shared-bindings/qrio/PixelPolicy.h b/shared-bindings/qrio/PixelPolicy.h new file mode 100644 index 0000000000..8be5dde1cc --- /dev/null +++ b/shared-bindings/qrio/PixelPolicy.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/enum.h" +#include "py/obj.h" +#include "py/objnamedtuple.h" + +extern const mp_obj_type_t qrio_pixel_policy_type; + +typedef enum { + QRIO_EVERY_BYTE, QRIO_EVEN_BYTES, QRIO_ODD_BYTES +} qrio_pixel_policy_t; + +extern const cp_enum_obj_t qrio_pixel_policy_EVERY_BYTE_obj; diff --git a/shared-bindings/qrio/QRDecoder.c b/shared-bindings/qrio/QRDecoder.c new file mode 100644 index 0000000000..73a5d64694 --- /dev/null +++ b/shared-bindings/qrio/QRDecoder.c @@ -0,0 +1,155 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/qrio/__init__.h" +#include "shared-bindings/qrio/QRDecoder.h" +#include "shared-module/qrio/QRDecoder.h" + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/enum.h" + +//| class QRDecoder: +//| +//| def __init__(self, width: int, height: int) -> None: +//| """Construct a QRDecoder object +//| +//| :param int width: The pixel width of the image to decode +//| :param int height: The pixel height of the image to decode +//| """ +//| ... + +STATIC mp_obj_t qrio_qrdecoder_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_height }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + }; + 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); + + qrio_qrdecoder_obj_t *self = m_new_obj(qrio_qrdecoder_obj_t); + self->base.type = &qrio_qrdecoder_type_obj; + shared_module_qrio_qrdecoder_construct(self, args[ARG_width].u_int, args[ARG_height].u_int); + + return self; +} + +//| def decode(self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE) -> List[QRInfo]: +//| """Decode zero or more QR codes from the given image. The size of the buffer must be at least ``length``×``width`` bytes for `EVERY_BYTE`, and 2×``length``×``width`` bytes for `EVEN_BYTES` or `ODD_BYTES`.""" +//| +STATIC mp_obj_t qrio_qrdecoder_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_buffer, ARG_pixel_policy }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_pixel_policy, MP_ARG_OBJ, {.u_obj = MP_ROM_PTR((mp_obj_t *)&qrio_pixel_policy_EVERY_BYTE_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); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + int width = shared_module_qrio_qrdecoder_get_width(self); + int height = shared_module_qrio_qrdecoder_get_height(self); + + // verify that the buffer is big enough + int sz = width * height; + qrio_pixel_policy_t policy = cp_enum_value(&qrio_pixel_policy_type, args[ARG_pixel_policy].u_obj); + if (policy != QRIO_EVERY_BYTE) { + sz *= 2; + } + mp_get_index(mp_obj_get_type(args[ARG_buffer].u_obj), bufinfo.len, MP_OBJ_NEW_SMALL_INT(sz - 1), false); + + return shared_module_qrio_qrdecoder_decode(self, &bufinfo, policy); +} +MP_DEFINE_CONST_FUN_OBJ_KW(qrio_qrdecoder_decode_obj, 2, qrio_qrdecoder_decode); + +//| width: int +//| """The width of image the decoder expects""" +//| +STATIC mp_obj_t qrio_qrdecoder_get_width(mp_obj_t self_in) { + qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(shared_module_qrio_qrdecoder_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(qrio_qrdecoder_get_width_obj, qrio_qrdecoder_get_width); + +STATIC mp_obj_t qrio_qrdecoder_set_width(mp_obj_t self_in, mp_obj_t width_in) { + qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + int width = mp_obj_get_int(width_in); + shared_module_qrio_qrdecoder_set_width(self, width); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(qrio_qrdecoder_set_width_obj, qrio_qrdecoder_set_width); + +const mp_obj_property_t qrio_qrdecoder_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&qrio_qrdecoder_get_width_obj, + (mp_obj_t)&qrio_qrdecoder_set_width_obj, + MP_ROM_NONE}, +}; + +//| height: int +//| """The height of image the decoder expects""" +//| +STATIC mp_obj_t qrio_qrdecoder_get_height(mp_obj_t self_in) { + qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(shared_module_qrio_qrdecoder_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(qrio_qrdecoder_get_height_obj, qrio_qrdecoder_get_height); + +STATIC mp_obj_t qrio_qrdecoder_set_height(mp_obj_t self_in, mp_obj_t height_in) { + qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); + int height = mp_obj_get_int(height_in); + shared_module_qrio_qrdecoder_set_height(self, height); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(qrio_qrdecoder_set_height_obj, qrio_qrdecoder_set_height); + +const mp_obj_property_t qrio_qrdecoder_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&qrio_qrdecoder_get_height_obj, + (mp_obj_t)&qrio_qrdecoder_set_height_obj, + MP_ROM_NONE}, +}; + +STATIC const mp_rom_map_elem_t qrio_qrdecoder_locals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_QRDecoder) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&qrio_qrdecoder_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&qrio_qrdecoder_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&qrio_qrdecoder_decode_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(qrio_qrdecoder_locals, qrio_qrdecoder_locals_table); + +const mp_obj_type_t qrio_qrdecoder_type_obj = { + { &mp_type_type }, + .name = MP_QSTR_QRDecoder, + .make_new = qrio_qrdecoder_make_new, + .locals_dict = (mp_obj_dict_t *)&qrio_qrdecoder_locals, +}; diff --git a/shared-bindings/qrio/QRDecoder.h b/shared-bindings/qrio/QRDecoder.h new file mode 100644 index 0000000000..0b01aeb44e --- /dev/null +++ b/shared-bindings/qrio/QRDecoder.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct qrio_qrdecoder_obj qrio_qrdecoder_obj_t; + +extern const mp_obj_type_t qrio_qrdecoder_type_obj; + +void common_hal_qrio_qrdecoder_construct(qrio_qrdecoder_obj_t *self); + +mp_obj_t common_hal_qrio_qrdecoder_decode(qrio_qrdecoder_obj_t *self, int width, int height, mp_buffer_info_t *buf); diff --git a/shared-bindings/qrio/QRInfo.c b/shared-bindings/qrio/QRInfo.c new file mode 100644 index 0000000000..8eb03874ef --- /dev/null +++ b/shared-bindings/qrio/QRInfo.c @@ -0,0 +1,64 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/qrio/__init__.h" +#include "shared-bindings/qrio/QRInfo.h" +#include "py/obj.h" +#include "py/enum.h" + +//| class QRInfo: +//| """Information about a decoded QR code""" +//| +//| payload: bytes +//| """The content of the QR code""" +//| +//| data_type: Union[str, int] +//| """The encoding of the payload as a string (if a standard encoding) or int (if not standard)""" + +const mp_obj_namedtuple_type_t qrio_qrinfo_type_obj = { + .base = { + .base = { + .type = &mp_type_type + }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_QRInfo, + .print = namedtuple_print, + .parent = &mp_type_tuple, + .make_new = namedtuple_make_new, + .attr = namedtuple_attr, + MP_TYPE_EXTENDED_FIELDS( + .unary_op = mp_obj_tuple_unary_op, + .binary_op = mp_obj_tuple_binary_op, + .subscr = mp_obj_tuple_subscr, + .getiter = mp_obj_tuple_getiter, + ), + }, + .n_fields = 2, + .fields = { + MP_QSTR_payload, + MP_QSTR_data_type, + }, +}; diff --git a/shared-bindings/qrio/QRInfo.h b/shared-bindings/qrio/QRInfo.h new file mode 100644 index 0000000000..956cb42735 --- /dev/null +++ b/shared-bindings/qrio/QRInfo.h @@ -0,0 +1,31 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/objnamedtuple.h" + +extern const mp_obj_namedtuple_type_t qrio_qrinfo_type_obj; diff --git a/shared-bindings/qrio/__init__.c b/shared-bindings/qrio/__init__.c new file mode 100644 index 0000000000..b848190d7e --- /dev/null +++ b/shared-bindings/qrio/__init__.c @@ -0,0 +1,53 @@ +/* + * This file is part of the CircuitPython project, https://github.com/adafruit/circuitpython + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/qrio/__init__.h" +#include "shared-bindings/qrio/QRDecoder.h" +#include "shared-bindings/qrio/QRInfo.h" +#include "shared-bindings/qrio/PixelPolicy.h" +#include "py/obj.h" +#include "py/enum.h" + +//| """`qrio` module. +//| +//| Provides the `QRDecoder` object.""" +//| + +STATIC const mp_rom_map_elem_t qrio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_qrio) }, + { MP_ROM_QSTR(MP_QSTR_QRInfo), MP_ROM_PTR(&qrio_qrinfo_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_QRDecoder), MP_ROM_PTR(&qrio_qrdecoder_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_PixelPolicy), MP_ROM_PTR(&qrio_pixel_policy_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(qrio_module_globals, qrio_module_globals_table); + +const mp_obj_module_t qrio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&qrio_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_qrio, qrio_module, CIRCUITPY_QRIO); diff --git a/shared-bindings/qrio/__init__.h b/shared-bindings/qrio/__init__.h new file mode 100644 index 0000000000..be9b3aefa7 --- /dev/null +++ b/shared-bindings/qrio/__init__.h @@ -0,0 +1,27 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index 055b3a9084..05d3827489 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -32,6 +32,7 @@ #include "lib/utils/interrupt_char.h" #include "supervisor/shared/autoreload.h" +#include "supervisor/shared/bluetooth/bluetooth.h" #include "supervisor/shared/status_leds.h" #include "supervisor/shared/stack.h" #include "supervisor/shared/traceback.h" @@ -283,6 +284,21 @@ STATIC mp_obj_t supervisor_get_previous_traceback(void) { } MP_DEFINE_CONST_FUN_OBJ_0(supervisor_get_previous_traceback_obj, supervisor_get_previous_traceback); +//| def disable_ble_workflow() -> None: +//| """Disable ble workflow until a reset. This prevents BLE advertising outside of the VM and +//| the services used for it.""" +//| ... +//| +STATIC mp_obj_t supervisor_disable_ble_workflow(void) { + #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE + mp_raise_NotImplementedError(NULL); + #else + supervisor_bluetooth_disable_workflow(); + #endif + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_disable_ble_workflow_obj, supervisor_disable_ble_workflow); + STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, { MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, @@ -295,6 +311,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_set_next_code_file), MP_ROM_PTR(&supervisor_set_next_code_file_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&supervisor_ticks_ms_obj) }, { MP_ROM_QSTR(MP_QSTR_get_previous_traceback), MP_ROM_PTR(&supervisor_get_previous_traceback_obj) }, + { MP_ROM_QSTR(MP_QSTR_disable_ble_workflow), MP_ROM_PTR(&supervisor_disable_ble_workflow_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table); diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c new file mode 100644 index 0000000000..c12175f89b --- /dev/null +++ b/shared-bindings/traceback/__init__.c @@ -0,0 +1,172 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * 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/stream.h" +#include "py/runtime.h" + +#include "shared-module/traceback/__init__.h" + +//| """Traceback Module +//| +//| This module provides a standard interface to print stack traces of programs. +//| This is useful when you want to print stack traces under program control. +//| +//| """ +//| ... +//| + +STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj_t tb_obj, mp_obj_t limit_obj) { + if (!mp_obj_is_exception_instance(value)) { + mp_raise_TypeError(translate("invalid exception")); + } + mp_obj_exception_t exc = *(mp_obj_exception_t *)MP_OBJ_TO_PTR(value); + + mp_int_t limit = 0; + bool print_tb = true; + if (limit_obj != mp_const_none) { + limit = mp_obj_get_int(limit_obj); + print_tb = (limit != 0); + } + + if (tb_obj != mp_const_none && print_tb) { + if (!mp_obj_is_type(tb_obj, &mp_type_traceback)) { + mp_raise_TypeError(translate("invalid traceback")); + } + exc.traceback = MP_OBJ_TO_PTR(tb_obj); + } else { + exc.traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + } + + shared_module_traceback_print_exception(&exc, print, limit); +} + +//| def format_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, +//| limit: Optional[int] = None, chain: Optional[bool] = True) -> None: +//| """Format a stack trace and the exception information. +//| +//| The arguments have the same meaning as the corresponding arguments +//| to print_exception(). The return value is a list of strings, each +//| ending in a newline and some containing internal newlines. When +//| these lines are concatenated and printed, exactly the same text is +//| printed as does print_exception(). +//| +//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented. +//| +//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``. +//| :param BaseException value: The exception. Must be an instance of `BaseException`. +//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed. +//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. +//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. +//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented). +//| +//| """ +//| ... +//| +STATIC mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_chain }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_chain, 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_print_t print; + vstr_t vstr; + vstr_init_print(&vstr, 0, &print); + traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 3, traceback_format_exception); + +//| def print_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, +//| limit: Optional[int] = None, file: Optional[io.FileIO] = None, chain: Optional[bool] = True) -> None: +//| +//| """Prints exception information and stack trace entries. +//| +//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented. +//| +//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``. +//| :param BaseException value: The exception. Must be an instance of `BaseException`. +//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed. +//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. +//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. +//| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open +//| file or file-like object to receive the output. +//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented). +//| +//| """ +//| ... +//| + +STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_file, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_chain, 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_print_t print = mp_plat_print; + if (args[ARG_file].u_obj != mp_const_none) { + #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES + mp_get_stream_raise(args[ARG_file].u_obj, MP_STREAM_OP_WRITE); + print.data = MP_OBJ_TO_PTR(args[ARG_file].u_obj); + print.print_strn = mp_stream_write_adaptor; + #else + mp_raise_NotImplementedError(translate("file write is not available")); + #endif + } + + traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_print_exception_obj, 3, traceback_print_exception); + +STATIC const mp_rom_map_elem_t traceback_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_traceback) }, + // module functions + { MP_ROM_QSTR(MP_QSTR_format_exception), MP_ROM_PTR(&traceback_format_exception_obj) }, + { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&traceback_print_exception_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(traceback_module_globals, traceback_module_globals_table); + +const mp_obj_module_t traceback_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&traceback_module_globals, +}; diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 64803f8e13..718df73241 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -31,7 +31,7 @@ //| class Device: //| """HID Device specification""" //| -//| def __init__(self, *, descriptor: ReadableBuffer, usage_page: int, usage: int, in_report_length: int, out_report_length: int = 0, report_id_index: Optional[int]) -> None: +//| def __init__(self, *, descriptor: ReadableBuffer, usage_page: int, usage: int, report_ids: Sequence[int], in_report_lengths: Sequence[int], out_report_lengths: Sequence[int]) -> None: //| """Create a description of a USB HID device. The actual device is created when you //| pass a `Device` to `usb_hid.enable()`. //| @@ -39,38 +39,46 @@ //| not verified for correctness; it is up to you to make sure it is not malformed. //| :param int usage_page: The Usage Page value from the descriptor. Must match what is in the descriptor. //| :param int usage: The Usage value from the descriptor. Must match what is in the descriptor. -//| :param int in_report_length: Size in bytes of the HID report sent to the host. -//| "In" is with respect to the host. -//| :param int out_report_length: Size in bytes of the HID report received from the host. -//| "Out" is with respect to the host. If no reports are expected, use 0. -//| :param int report_id_index: position of byte in descriptor that contains the Report ID. -//| A Report ID will be assigned when the device is created. If there is no -//| Report ID, use ``None``. +//| :param int report_ids: Sequence of report ids used by the descriptor. +//| If the ``report_descriptor`` does not have a report ID, use 0. +//| :param int in_report_lengths: Sequence of sizes in bytes of the HIDs report sent to the host. +//| The sizes are in order of the ``report_ids``. +//| "IN" is with respect to the host. +//| :param int out_report_lengths: Size in bytes of the HID report received from the host. +//| The sizes are in order of the ``report_ids``. +//| "OUT" is with respect to the host. +//| +//| ``report_ids``, ``in_report_lengths``, and ``out_report_lengths`` must all be the same length. //| """ //| ... //| //| KEYBOARD: Device -//| """Standard keyboard device supporting keycodes 0x00-0xDD, modifiers 0xE-0xE7, and five LED indicators.""" +//| """Standard keyboard device supporting keycodes 0x00-0xDD, modifiers 0xE-0xE7, and five LED indicators. +//| Uses Report ID 1 for its IN and OUT reports. +//| """ //| //| MOUSE: Device //| """Standard mouse device supporting five mouse buttons, X and Y relative movements from -127 to 127 -//| in each report, and a relative mouse wheel change from -127 to 127 in each report.""" +//| in each report, and a relative mouse wheel change from -127 to 127 in each report. +//| Uses Report ID 2 for its IN report. +//| """ //| //| CONSUMER_CONTROL: Device -//| """Consumer Control device supporting sent values from 1-652, with no rollover.""" +//| """Consumer Control device supporting sent values from 1-652, with no rollover. +//| Uses Report ID 3 for its IN report.""" //| STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { usb_hid_device_obj_t *self = m_new_obj(usb_hid_device_obj_t); self->base.type = &usb_hid_device_type; - enum { ARG_report_descriptor, ARG_usage_page, ARG_usage, ARG_in_report_length, ARG_out_report_length, ARG_report_id_index }; + enum { ARG_report_descriptor, ARG_usage_page, ARG_usage, ARG_report_ids, ARG_in_report_lengths, ARG_out_report_lengths }; static const mp_arg_t allowed_args[] = { { MP_QSTR_report_descriptor, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_usage_page, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_usage, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_in_report_length, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_out_report_length, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0 } }, - { MP_QSTR_report_id_index, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none } }, + { MP_QSTR_report_ids, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_in_report_lengths, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_out_report_lengths, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -81,82 +89,144 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args mp_obj_t descriptor = mp_obj_new_bytearray(descriptor_bufinfo.len, descriptor_bufinfo.buf); const mp_int_t usage_page_arg = args[ARG_usage_page].u_int; - if (usage_page_arg <= 0 || usage_page_arg > 255) { - mp_raise_ValueError_varg(translate("%q must be 1-255"), MP_QSTR_usage_page); - } + mp_arg_validate_int_range(usage_page_arg, 1, 255, MP_QSTR_usage_page); const uint8_t usage_page = usage_page_arg; const mp_int_t usage_arg = args[ARG_usage].u_int; - if (usage_arg <= 0 || usage_arg > 255) { - mp_raise_ValueError_varg(translate("%q must be 1-255"), MP_QSTR_usage); - } + mp_arg_validate_int_range(usage_arg, 1, 255, MP_QSTR_usage_page); const uint8_t usage = usage_arg; - const mp_int_t in_report_length_arg = args[ARG_in_report_length].u_int; - if (in_report_length_arg <= 0 || in_report_length_arg > 255) { - mp_raise_ValueError_varg(translate("%q must be 1-255"), MP_QSTR_in_report_length); - } - const uint8_t in_report_length = in_report_length_arg; + mp_obj_t report_ids = args[ARG_report_ids].u_obj; + mp_obj_t in_report_lengths = args[ARG_in_report_lengths].u_obj; + mp_obj_t out_report_lengths = args[ARG_out_report_lengths].u_obj; - const mp_int_t out_report_length_arg = args[ARG_out_report_length].u_int; - if (out_report_length_arg < 0 || out_report_length_arg > 255) { - mp_raise_ValueError_varg(translate("%q must be 0-255"), MP_QSTR_out_report_length); + size_t report_ids_count = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(report_ids)); + if (report_ids_count < 1) { + mp_raise_ValueError_varg(translate("%q length must be >= 1"), MP_QSTR_report_ids); } - const uint8_t out_report_length = out_report_length_arg; - const mp_obj_t report_id_index_arg = args[ARG_report_id_index].u_obj; - uint8_t report_id_index = 0; - if (report_id_index_arg != mp_const_none) { - const mp_int_t report_id_index_int = mp_obj_int_get_checked(report_id_index_arg); - if (report_id_index_int <= 0 || (uint32_t)report_id_index_int >= descriptor_bufinfo.len) { - mp_raise_ValueError_varg(translate("%q must be None or between 1 and len(report_descriptor)-1"), - MP_QSTR_report_id_index); - } - report_id_index = report_id_index_int; + if ((size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(in_report_lengths)) != report_ids_count || + (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(out_report_lengths)) != report_ids_count) { + mp_raise_ValueError_varg(translate("%q, %q, and %q must all be the same length"), + MP_QSTR_report_ids, MP_QSTR_in_report_lengths, MP_QSTR_out_report_lengths); + } + + uint8_t report_ids_array[report_ids_count]; + uint8_t in_report_lengths_array[report_ids_count]; + uint8_t out_report_lengths_array[report_ids_count]; + + // Validate the ids and lengths are all integers in range. + for (size_t i = 0; i < report_ids_count; i++) { + mp_obj_t i_obj = MP_OBJ_NEW_SMALL_INT(i); + + report_ids_array[i] = (uint8_t)mp_arg_validate_int_range( + // It's not the actual argument that's out of range, but its elements. + // But the error message is close enough. + MP_OBJ_SMALL_INT_VALUE(mp_obj_subscr(report_ids, i_obj, MP_OBJ_SENTINEL)), + 1, 255, MP_QSTR_report_ids); + + in_report_lengths_array[i] = (uint8_t)mp_arg_validate_int_range( + MP_OBJ_SMALL_INT_VALUE(mp_obj_subscr(in_report_lengths_array, i_obj, MP_OBJ_SENTINEL)), + 0, 255, MP_QSTR_in_report_lengths); + + out_report_lengths_array[i] = (uint8_t)mp_arg_validate_int_range( + MP_OBJ_SMALL_INT_VALUE(mp_obj_subscr(out_report_lengths_array, i_obj, MP_OBJ_SENTINEL)), + 0, 255, MP_QSTR_out_report_lengths); } common_hal_usb_hid_device_construct( - self, descriptor, usage_page, usage, in_report_length, out_report_length, report_id_index); + self, descriptor, usage_page, usage, report_ids_count, report_ids_array, in_report_lengths_array, out_report_lengths_array); return (mp_obj_t)self; } -//| def send_report(self, buf: ReadableBuffer) -> None: -//| """Send a HID report.""" +//| def send_report(self, buf: ReadableBuffer, report_id: Optional[int] = None) -> None: +//| """Send an HID report. If the device descriptor specifies zero or one report id's, +//| you can supply `None` (the default) as the value of ``report_id``. +//| Otherwise you must specify which report id to use when sending the report. +//| """ //| ... //| -STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { - usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_buf, ARG_report_id }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_report_id, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + 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(buffer, &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ); - common_hal_usb_hid_device_send_report(self, ((uint8_t *)bufinfo.buf), bufinfo.len); + // -1 asks common_hal to determine the report id if possible. + mp_int_t report_id_arg = -1; + if (args[ARG_report_id].u_obj != mp_const_none) { + report_id_arg = mp_obj_int_get_checked(args[ARG_report_id].u_obj); + } + const uint8_t report_id = common_hal_usb_hid_device_validate_report_id(self, report_id_arg); + + common_hal_usb_hid_device_send_report(self, ((uint8_t *)bufinfo.buf), bufinfo.len, report_id); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); +MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_device_send_report_obj, 2, usb_hid_device_send_report); + +//| def get_last_received_report(self, report_id: Optional[int] = None) -> bytes: +//| """Get the last received HID OUT report for the given report ID. +//| The report ID may be omitted if there is no report ID, or only one report ID. +//| Return `None` if nothing received. +//| """ +//| ... +//| +STATIC mp_obj_t usb_hid_device_get_last_received_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + enum { ARG_report_id }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_report_id, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t report_id_arg = -1; + if (args[ARG_report_id].u_obj != mp_const_none) { + report_id_arg = mp_obj_int_get_checked(args[ARG_report_id].u_obj); + } + const uint8_t report_id = common_hal_usb_hid_device_validate_report_id(self, report_id_arg); + + return common_hal_usb_hid_device_get_last_received_report(self, report_id); +} +MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_device_get_last_received_report_obj, 1, usb_hid_device_get_last_received_report); //| last_received_report: bytes -//| """The HID OUT report as a `bytes`. (read-only). `None` if nothing received.""" +//| """The HID OUT report as a `bytes` (read-only). `None` if nothing received. +//| Same as `get_last_received_report()` with no argument. //| -STATIC mp_obj_t usb_hid_device_obj_get_last_received_report(mp_obj_t self_in) { +//| Deprecated: will be removed in CircutPython 8.0.0. Use `get_last_received_report()` instead. +//| """ +//| +STATIC mp_obj_t usb_hid_device_obj_get_last_received_report_property(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->out_report_buffer == 0) { - return mp_const_none; - } - return mp_obj_new_bytes(self->out_report_buffer, self->out_report_length); + + // Get the sole report_id, if there is one. + const uint8_t report_id = common_hal_usb_hid_device_validate_report_id(self, -1); + return common_hal_usb_hid_device_get_last_received_report(self, report_id); } -MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_last_received_report_obj, usb_hid_device_obj_get_last_received_report); +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_last_received_report_property_obj, usb_hid_device_obj_get_last_received_report_property); const mp_obj_property_t usb_hid_device_last_received_report_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&usb_hid_device_get_last_received_report_obj, + .proxy = {(mp_obj_t)&usb_hid_device_get_last_received_report_property_obj, MP_ROM_NONE, MP_ROM_NONE}, }; //| usage_page: int -//| """The usage page of the device as an `int`. Can be thought of a category. (read-only)""" +//| """The device usage page identifier, which designates a category of device. (read-only)""" //| STATIC mp_obj_t usb_hid_device_obj_get_usage_page(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -172,7 +242,7 @@ const mp_obj_property_t usb_hid_device_usage_page_obj = { }; //| usage: int -//| """The functionality of the device as an int. (read-only) +//| """The device usage identifier, which designates a specific kind of device. (read-only) //| //| For example, Keyboard is 0x06 within the generic desktop usage page 0x01. //| Mouse is 0x02 within the same usage page.""" @@ -192,13 +262,15 @@ const mp_obj_property_t usb_hid_device_usage_obj = { }; STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_last_received_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj) }, - { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj) }, - { MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&usb_hid_device_keyboard_obj) }, - { MP_ROM_QSTR(MP_QSTR_MOUSE), MP_ROM_PTR(&usb_hid_device_mouse_obj) }, - { MP_ROM_QSTR(MP_QSTR_CONSUMER_CONTROL), MP_ROM_PTR(&usb_hid_device_consumer_control_obj) }, + { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_last_received_report), MP_ROM_PTR(&usb_hid_device_get_last_received_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_last_received_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj) }, + + { MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&usb_hid_device_keyboard_obj) }, + { MP_ROM_QSTR(MP_QSTR_MOUSE), MP_ROM_PTR(&usb_hid_device_mouse_obj) }, + { MP_ROM_QSTR(MP_QSTR_CONSUMER_CONTROL), MP_ROM_PTR(&usb_hid_device_consumer_control_obj) }, }; STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table); diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h index c1af92fd4f..a5e94c4d52 100644 --- a/shared-bindings/usb_hid/Device.h +++ b/shared-bindings/usb_hid/Device.h @@ -33,9 +33,11 @@ extern const mp_obj_type_t usb_hid_device_type; -void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t descriptor, uint8_t usage_page, uint8_t usage, uint8_t in_report_length, uint8_t out_report_length, uint8_t report_id_index); -void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len); +void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint8_t usage_page, uint8_t usage, size_t report_ids_count,uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths); +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len, uint8_t report_id); +mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id); uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self); uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self); +uint8_t common_hal_usb_hid_device_validate_report_id(usb_hid_device_obj_t *self, mp_int_t report_id); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c index f5a7c1cf72..1c8a45e4ea 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -71,7 +71,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_disable_obj, usb_hid_disable); //| //| If you enable too many devices at once, you will run out of USB endpoints. //| The number of available endpoints varies by microcontroller. -//| CircuitPython will go into safe mode after running boot.py to inform you if +//| CircuitPython will go into safe mode after running ``boot.py`` to inform you if //| not enough endpoints are available. //| """ //| ... diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index 673a976687..c0cc0bbcc2 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -1,5 +1,6 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-bindings/vectorio/Circle.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -11,15 +12,21 @@ //| class Circle: //| -//| def __init__(self, radius: int) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], radius: int, x: int, y: int) -> None: //| """Circle is positioned on screen by its center point. //| -//| :param radius: The radius of the circle in pixels""" +//| :param pixel_shader: The pixel shader that produces colors from values +//| :param radius: The radius of the circle in pixels +//| :param x: Initial x position of the axis. +//| :param y: Initial y position of the axis.""" //| static mp_obj_t vectorio_circle_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_radius }; + enum { ARG_pixel_shader, ARG_radius, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; 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); @@ -33,9 +40,22 @@ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_arg self->base.type = &vectorio_circle_type; common_hal_vectorio_circle_construct(self, radius); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t circle_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_circle_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; + //| radius : int //| """The radius of the circle in pixels.""" @@ -62,13 +82,22 @@ const mp_obj_property_t vectorio_circle_radius_obj = { STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { + // Properties { MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) }, + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_circle_locals_dict, vectorio_circle_locals_dict_table); const mp_obj_type_t vectorio_circle_type = { { &mp_type_type }, .name = MP_QSTR_Circle, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_circle_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_circle_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &circle_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Circle.h b/shared-bindings/vectorio/Circle.h index e8fc048eb8..37bbe9e65b 100644 --- a/shared-bindings/vectorio/Circle.h +++ b/shared-bindings/vectorio/Circle.h @@ -19,4 +19,6 @@ void common_hal_vectorio_circle_get_area(void *circle, displayio_area_t *out_are int16_t common_hal_vectorio_circle_get_radius(void *circle); void common_hal_vectorio_circle_set_radius(void *circle, int16_t radius); +mp_obj_t common_hal_vectorio_circle_get_draw_protocol(void *circle); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 23c7961ec7..5d493a30b6 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -1,6 +1,7 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-module/vectorio/__init__.h" #include "shared-bindings/vectorio/Polygon.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -16,15 +17,21 @@ //| class Polygon: -//| def __init__(self, points: List[Tuple[int, int]]) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], points: List[Tuple[int, int]], x: int, y: int) -> None: //| """Represents a closed shape by ordered vertices //| -//| :param points: Vertices for the polygon""" +//| :param pixel_shader: The pixel shader that produces colors from values +//| :param points: Vertices for the polygon +//| :param x: Initial screen x position of the 0,0 origin in the points list. +//| :param y: Initial screen y position of the 0,0 origin in the points list.""" //| static mp_obj_t vectorio_polygon_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_points_list }; + enum { ARG_pixel_shader, ARG_points_list, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; 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); @@ -38,9 +45,22 @@ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_ar common_hal_vectorio_polygon_construct(self, args[ARG_points_list].u_obj); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t polygon_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_polygon_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; + //| points: List[Tuple[int, int]] //| """Set a new look and shape for this polygon""" @@ -67,13 +87,22 @@ const mp_obj_property_t vectorio_polygon_points_obj = { }; STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { + // Properties { MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) }, + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_polygon_locals_dict, vectorio_polygon_locals_dict_table); const mp_obj_type_t vectorio_polygon_type = { { &mp_type_type }, .name = MP_QSTR_Polygon, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_polygon_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_polygon_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &polygon_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Polygon.h b/shared-bindings/vectorio/Polygon.h index 5594fbec4a..68136be6bd 100644 --- a/shared-bindings/vectorio/Polygon.h +++ b/shared-bindings/vectorio/Polygon.h @@ -20,5 +20,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *out_a mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self); void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list); +mp_obj_t common_hal_vectorio_polygon_get_draw_protocol(void *polygon); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index a50a8a14b3..aa2c166a6d 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -1,5 +1,7 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-bindings/vectorio/Rectangle.h" +#include "shared-module/vectorio/VectorShape.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -8,17 +10,23 @@ #include "supervisor/shared/translate.h" //| class Rectangle: -//| def __init__(self, width: int, height: int) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], width: int, height: int, x: int, y: int) -> None: //| """Represents a rectangle by defining its bounds //| +//| :param pixel_shader: The pixel shader that produces colors from values //| :param width: The number of pixels wide -//| :param height: The number of pixels high""" +//| :param height: The number of pixels high +//| :param x: Initial x position of the top left corner. +//| :param y: Initial y position of the top left corner.""" //| static mp_obj_t vectorio_rectangle_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_height }; + enum { ARG_pixel_shader, ARG_width, ARG_height, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; 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); @@ -36,17 +44,38 @@ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_ self->base.type = &vectorio_rectangle_type; common_hal_vectorio_rectangle_construct(self, width, height); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t rectangle_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_rectangle_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_rectangle_locals_dict, vectorio_rectangle_locals_dict_table); const mp_obj_type_t vectorio_rectangle_type = { { &mp_type_type }, .name = MP_QSTR_Rectangle, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_rectangle_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_rectangle_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &rectangle_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Rectangle.h b/shared-bindings/vectorio/Rectangle.h index bb461ed9d5..24b103c26e 100644 --- a/shared-bindings/vectorio/Rectangle.h +++ b/shared-bindings/vectorio/Rectangle.h @@ -12,4 +12,6 @@ uint32_t common_hal_vectorio_rectangle_get_pixel(void *rectangle, int16_t x, int void common_hal_vectorio_rectangle_get_area(void *rectangle, displayio_area_t *out_area); +mp_obj_t common_hal_vectorio_rectangle_get_draw_protocol(void *rectangle); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index ae8532eb95..6e4299a6d3 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -19,37 +19,16 @@ #include "supervisor/shared/translate.h" -//| class VectorShape: -//| def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None: -//| """Binds a vector shape to a location and pixel color -//| -//| :param shape: The shape to draw. -//| :param pixel_shader: The pixel shader that produces colors from values -//| :param x: Initial x position of the center axis of the shape within the parent. -//| :param y: Initial y position of the center axis of the shape within the parent.""" -//| ... -//| -STATIC mp_obj_t vectorio_vector_shape_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_shape, ARG_pixel_shader, ARG_x, ARG_y }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_shape, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; +// shape: The shape implementation to draw. +// pixel_shader: The pixel shader that produces colors from values. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0. +// x: Initial x position of the center axis of the shape within the parent. +// y: Initial y position of the center axis of the shape within the parent.""" +mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pixel_shader, int16_t x, int16_t y) { if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) && !mp_obj_is_type(pixel_shader, &displayio_palette_type)) { mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); } - int16_t x = args[ARG_x].u_int; - int16_t y = args[ARG_y].u_int; - - mp_obj_t shape = args[ARG_shape].u_obj; vectorio_ishape_t ishape; // Wire up shape functions if (mp_obj_is_type(shape, &vectorio_polygon_type)) { @@ -92,18 +71,32 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t return MP_OBJ_FROM_PTR(self); } +vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl = { + .draw_fill_area = (draw_fill_area_fun)vectorio_vector_shape_fill_area, + .draw_get_dirty_area = (draw_get_dirty_area_fun)vectorio_vector_shape_get_dirty_area, + .draw_update_transform = (draw_update_transform_fun)vectorio_vector_shape_update_transform, + .draw_finish_refresh = (draw_finish_refresh_fun)vectorio_vector_shape_finish_refresh, + .draw_get_refresh_areas = (draw_get_refresh_areas_fun)vectorio_vector_shape_get_refresh_areas, +}; + + +// Stub checker does not approve of these shared properties. +// x: int +// """X position of the center point of the shape in the parent.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); -//| x: int -//| """X position of the center point of the shape in the parent.""" -//| -STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_x(self)); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_x_obj, vectorio_vector_shape_obj_get_x); -STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t wrapper_shape, mp_obj_t x_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); mp_int_t x = mp_obj_get_int(x_obj); common_hal_vectorio_vector_shape_set_x(self, x); @@ -119,17 +112,22 @@ const mp_obj_property_t vectorio_vector_shape_x_obj = { }; -//| y: int -//| """Y position of the center point of the shape in the parent.""" -//| -STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +// y: int +// """Y position of the center point of the shape in the parent.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_y(self)); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_y_obj, vectorio_vector_shape_obj_get_y); -STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t wrapper_shape, mp_obj_t y_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); mp_int_t y = mp_obj_get_int(y_obj); common_hal_vectorio_vector_shape_set_y(self, y); @@ -145,17 +143,53 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = { }; -//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] -//| """The pixel shader of the shape.""" -//| -STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +// location: Tuple[int, int] +// """location of the center point of the shape in the parent.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_location(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + + return MP_OBJ_TO_PTR(common_hal_vectorio_vector_shape_get_location(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_location_obj, vectorio_vector_shape_obj_get_location); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_location(mp_obj_t wrapper_shape, mp_obj_t location_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + + common_hal_vectorio_vector_shape_set_location(self, location_obj); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_location_obj, vectorio_vector_shape_obj_set_location); + +const mp_obj_property_t vectorio_vector_shape_location_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_vector_shape_get_location_obj, + (mp_obj_t)&vectorio_vector_shape_set_location_obj, + MP_ROM_NONE}, +}; + + +// pixel_shader: Union[ColorConverter, Palette] +// """The pixel shader of the shape.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return common_hal_vectorio_vector_shape_get_pixel_shader(self); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_pixel_shader_obj, vectorio_vector_shape_obj_get_pixel_shader); -STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t wrapper_shape, mp_obj_t pixel_shader) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); } @@ -175,16 +209,11 @@ const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj = { STATIC const mp_rom_map_elem_t vectorio_vector_shape_locals_dict_table[] = { - // Properties - { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, - { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_vector_shape_locals_dict, vectorio_vector_shape_locals_dict_table); const mp_obj_type_t vectorio_vector_shape_type = { { &mp_type_type }, .name = MP_QSTR_VectorShape, - .make_new = vectorio_vector_shape_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_vector_shape_locals_dict, }; diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h index fa11f73ffd..9ac6906000 100644 --- a/shared-bindings/vectorio/VectorShape.h +++ b/shared-bindings/vectorio/VectorShape.h @@ -1,11 +1,19 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H +#include "py/objproperty.h" +#include "py/objtuple.h" + +#include "shared-bindings/vectorio/__init__.h" #include "shared-module/vectorio/VectorShape.h" #include "shared-module/displayio/area.h" extern const mp_obj_type_t vectorio_vector_shape_type; +// Python shared bindings constructor +mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pixel_shader, int16_t x, int16_t y); + +// C data constructor void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, vectorio_ishape_t ishape, mp_obj_t pixel_shader, uint16_t x, uint16_t y); @@ -15,13 +23,22 @@ void common_hal_vectorio_vector_shape_set_dirty(void *self); mp_int_t common_hal_vectorio_vector_shape_get_x(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_x(vectorio_vector_shape_t *self, mp_int_t x); +mp_obj_tuple_t *common_hal_vectorio_vector_shape_get_location(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self, mp_obj_t xy); + mp_int_t common_hal_vectorio_vector_shape_get_y(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_int_t y); mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader); - void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform); +// Composable property definition for shapes that use VectorShape +extern vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl; +extern const mp_obj_property_t vectorio_vector_shape_x_obj; +extern const mp_obj_property_t vectorio_vector_shape_y_obj; +extern const mp_obj_property_t vectorio_vector_shape_location_obj; +extern const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj; + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 12fb4d72b1..5a3729573e 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -6,7 +6,6 @@ #include "shared-bindings/vectorio/Circle.h" #include "shared-bindings/vectorio/Polygon.h" #include "shared-bindings/vectorio/Rectangle.h" -#include "shared-bindings/vectorio/VectorShape.h" //| """Lightweight 2d shapes for displays""" //| @@ -16,7 +15,6 @@ STATIC const mp_rom_map_elem_t vectorio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Circle), MP_ROM_PTR(&vectorio_circle_type) }, { MP_ROM_QSTR(MP_QSTR_Polygon), MP_ROM_PTR(&vectorio_polygon_type) }, { MP_ROM_QSTR(MP_QSTR_Rectangle), MP_ROM_PTR(&vectorio_rectangle_type) }, - { MP_ROM_QSTR(MP_QSTR_VectorShape), MP_ROM_PTR(&vectorio_vector_shape_type) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_module_globals, vectorio_module_globals_table); diff --git a/shared-bindings/vectorio/__init__.h b/shared-bindings/vectorio/__init__.h new file mode 100644 index 0000000000..a34195de26 --- /dev/null +++ b/shared-bindings/vectorio/__init__.h @@ -0,0 +1,41 @@ +#ifndef SHARED_MODULE_VECTORIO__INIT__H +#define SHARED_MODULE_VECTORIO__INIT__H + +#include +#include + +#include "py/obj.h" +#include "py/proto.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" + +// Returns the object on which the rest of the draw protocol methods are invoked. +typedef mp_obj_t (*draw_get_protocol_self_fun)(mp_obj_t protocol_container); + +typedef bool (*draw_fill_area_fun)(mp_obj_t draw_protocol_self, const _displayio_colorspace_t *colorspace, const displayio_area_t *area, uint32_t *mask, uint32_t *buffer); +typedef bool (*draw_get_dirty_area_fun)(mp_obj_t draw_protocol_self, displayio_area_t *current_dirty_area); +typedef void (*draw_update_transform_fun)(mp_obj_t draw_protocol_self, displayio_buffer_transform_t *group_transform); +typedef void (*draw_finish_refresh_fun)(mp_obj_t draw_protocol_self); +typedef displayio_area_t *(*draw_get_refresh_areas_fun)(mp_obj_t draw_protocol_self, displayio_area_t *tail); + +typedef struct _vectorio_draw_protocol_impl_t { + draw_fill_area_fun draw_fill_area; + draw_get_dirty_area_fun draw_get_dirty_area; + draw_update_transform_fun draw_update_transform; + draw_finish_refresh_fun draw_finish_refresh; + draw_get_refresh_areas_fun draw_get_refresh_areas; +} vectorio_draw_protocol_impl_t; + +// Draw protocol +typedef struct _vectorio_draw_protocol_t { + MP_PROTOCOL_HEAD // MP_QSTR_protocol_draw + + // Instance of the draw protocol + draw_get_protocol_self_fun draw_get_protocol_self; + + // Implementation functions for the draw protocol + vectorio_draw_protocol_impl_t *draw_protocol_impl; +} vectorio_draw_protocol_t; + +#endif diff --git a/shared-bindings/watchdog/__init__.c b/shared-bindings/watchdog/__init__.c index 0911aca282..dbe06d1323 100644 --- a/shared-bindings/watchdog/__init__.c +++ b/shared-bindings/watchdog/__init__.c @@ -61,10 +61,8 @@ const mp_obj_type_t mp_type_WatchDogTimeout = { mp_obj_exception_t mp_watchdog_timeout_exception = { .base.type = &mp_type_WatchDogTimeout, - .traceback_alloc = 0, - .traceback_len = 0, - .traceback_data = NULL, .args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, + .traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj, }; STATIC const mp_rom_map_elem_t watchdog_module_globals_table[] = { diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c index 6d42d27ddb..14c92ca411 100644 --- a/shared-module/audiocore/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -206,7 +206,7 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t * } if (need_more_data) { - uint16_t num_bytes_to_load = self->len; + uint32_t num_bytes_to_load = self->len; if (num_bytes_to_load > self->bytes_remaining) { num_bytes_to_load = self->bytes_remaining; } diff --git a/shared-module/audiomp3/MP3Decoder.c b/shared-module/audiomp3/MP3Decoder.c index 27c69f735b..cc755d7d2f 100644 --- a/shared-module/audiomp3/MP3Decoder.c +++ b/shared-module/audiomp3/MP3Decoder.c @@ -319,6 +319,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * uint8_t **bufptr, uint32_t *buffer_length) { if (!self->inbuf) { + *buffer_length = 0; return GET_BUFFER_ERROR; } if (!single_channel_output) { @@ -342,6 +343,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * mp3file_skip_id3v2(self); if (!mp3file_find_sync_word(self)) { + *buffer_length = 0; return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR; } int bytes_left = BYTES_LEFT(self); @@ -349,6 +351,11 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * int err = MP3Decode(self->decoder, &inbuf, &bytes_left, buffer, 0); CONSUME(self, BYTES_LEFT(self) - bytes_left); + if (err) { + *buffer_length = 0; + return GET_BUFFER_DONE; + } + if (self->inbuf_offset >= 512) { background_callback_add( &self->inbuf_fill_cb, @@ -356,10 +363,6 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * self); } - if (err) { - return GET_BUFFER_DONE; - } - return GET_BUFFER_MORE_DATA; } diff --git a/shared-module/busio/OneWire.c b/shared-module/busio/OneWire.c deleted file mode 100644 index 80c55c7b2b..0000000000 --- a/shared-module/busio/OneWire.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of the Micro Python 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. - */ - -// Wraps the bitbangio implementation of OneWire for use in busio. -#include "common-hal/microcontroller/Pin.h" -#include "shared-bindings/bitbangio/OneWire.h" -#include "shared-module/busio/OneWire.h" - -void common_hal_busio_onewire_construct(busio_onewire_obj_t *self, - const mcu_pin_obj_t *pin) { - shared_module_bitbangio_onewire_construct(&self->bitbang, pin); -} - -bool common_hal_busio_onewire_deinited(busio_onewire_obj_t *self) { - return shared_module_bitbangio_onewire_deinited(&self->bitbang); -} - -void common_hal_busio_onewire_deinit(busio_onewire_obj_t *self) { - if (common_hal_busio_onewire_deinited(self)) { - return; - } - shared_module_bitbangio_onewire_deinit(&self->bitbang); -} - -bool common_hal_busio_onewire_reset(busio_onewire_obj_t *self) { - return shared_module_bitbangio_onewire_reset(&self->bitbang); -} - -bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t *self) { - return shared_module_bitbangio_onewire_read_bit(&self->bitbang); -} - -void common_hal_busio_onewire_write_bit(busio_onewire_obj_t *self, - bool bit) { - shared_module_bitbangio_onewire_write_bit(&self->bitbang, bit); -} diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index ec8ad7ba5a..b9179f0a00 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -144,10 +144,10 @@ static void _update_child_transforms(displayio_group_t *self) { for (size_t i = 0; i < self->members->len; i++) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - vectorio_vector_shape_update_transform(layer, &self->absolute_transform); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + draw_protocol->draw_protocol_impl->draw_update_transform(layer, &self->absolute_transform); continue; } #endif @@ -241,15 +241,14 @@ void common_hal_displayio_group_set_y(displayio_group_t *self, mp_int_t y) { } static void _add_layer(displayio_group_t *self, mp_obj_t layer) { - mp_obj_t native_layer; #if CIRCUITPY_VECTORIO - native_layer = mp_obj_cast_to_native_base(layer, &vectorio_vector_shape_type); - if (native_layer != MP_OBJ_NULL) { - vectorio_vector_shape_update_transform(native_layer, &self->absolute_transform); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, layer); + if (draw_protocol != NULL) { + draw_protocol->draw_protocol_impl->draw_update_transform(draw_protocol->draw_get_protocol_self(layer), &self->absolute_transform); return; } #endif - native_layer = mp_obj_cast_to_native_base(layer, &displayio_tilegrid_type); + mp_obj_t native_layer = mp_obj_cast_to_native_base(layer, &displayio_tilegrid_type); if (native_layer != MP_OBJ_NULL) { displayio_tilegrid_t *tilegrid = native_layer; if (tilegrid->in_group) { @@ -283,12 +282,12 @@ static void _remove_layer(displayio_group_t *self, size_t index) { displayio_area_t layer_area; bool rendered_last_frame = false; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[index], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[index]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[index]); + bool has_dirty_area = draw_protocol->draw_protocol_impl->draw_get_dirty_area(layer, &layer_area); rendered_last_frame = has_dirty_area; - vectorio_vector_shape_update_transform(layer, NULL); + draw_protocol->draw_protocol_impl->draw_update_transform(layer, NULL); } #endif layer = mp_obj_cast_to_native_base( @@ -362,10 +361,10 @@ bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorsp for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) { + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + if (draw_protocol->draw_protocol_impl->draw_fill_area(layer, colorspace, area, mask, buffer)) { return true; } continue; @@ -396,10 +395,10 @@ void displayio_group_finish_refresh(displayio_group_t *self) { for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - vectorio_vector_shape_finish_refresh(layer); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + draw_protocol->draw_protocol_impl->draw_finish_refresh(layer); continue; } #endif @@ -427,10 +426,10 @@ displayio_area_t *displayio_group_get_refresh_areas(displayio_group_t *self, dis for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - tail = vectorio_vector_shape_get_refresh_areas(layer, tail); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + tail = draw_protocol->draw_protocol_impl->draw_get_refresh_areas(layer, tail); continue; } #endif diff --git a/shared-bindings/busio/OneWire.h b/shared-module/getpass/__init__.c similarity index 53% rename from shared-bindings/busio/OneWire.h rename to shared-module/getpass/__init__.c index a270bab5c9..f7ab96c378 100644 --- a/shared-bindings/busio/OneWire.h +++ b/shared-module/getpass/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 microDev * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,20 +24,38 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H +#include "py/mphal.h" +#include "lib/mp-readline/readline.h" +#include "shared-module/getpass/__init__.h" -#include "common-hal/microcontroller/Pin.h" -#include "common-hal/busio/OneWire.h" +mp_obj_t shared_module_getpass_getpass(const char *prompt, mp_print_t *print) { + vstr_t vstr; + vstr_init(&vstr, 16); -extern const mp_obj_type_t busio_onewire_type; + if (print == NULL) { + mp_hal_stdout_tx_str(prompt); + } else { + mp_printf(print, prompt); + } -extern void common_hal_busio_onewire_construct(busio_onewire_obj_t *self, - const mcu_pin_obj_t *pin); -extern void common_hal_busio_onewire_deinit(busio_onewire_obj_t *self); -extern bool common_hal_busio_onewire_deinited(busio_onewire_obj_t *self); -extern bool common_hal_busio_onewire_reset(busio_onewire_obj_t *self); -extern bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t *self); -extern void common_hal_busio_onewire_write_bit(busio_onewire_obj_t *self, bool bit); + for (;;) { + int c = mp_hal_stdin_rx_chr(); + if (c == CHAR_CTRL_C) { + mp_raise_type(&mp_type_KeyboardInterrupt); + } else if (c == CHAR_CTRL_D && vstr.len == 0) { + mp_raise_type(&mp_type_EOFError); + } else if (c == 8 || c == 127) { + // backspace + vstr_cut_tail_bytes(&vstr, 1); + } else if (c >= 32) { + // printable character + vstr_ins_char(&vstr, vstr.len, c); + } else if (c == '\r') { + // newline + mp_hal_stdout_tx_str("\r\n"); + break; + } + } -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); +} diff --git a/shared-module/getpass/__init__.h b/shared-module/getpass/__init__.h new file mode 100644 index 0000000000..80595d41ba --- /dev/null +++ b/shared-module/getpass/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H + +#include "py/runtime.h" + +extern mp_obj_t shared_module_getpass_getpass(const char *prompt, mp_print_t *print); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index 88e9d09a83..6db012d0f6 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -77,8 +77,6 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) { diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index 1f232a03ed..2880d18de5 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -63,8 +63,6 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self) { diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index 074f226998..5075437214 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -71,8 +71,6 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self) { diff --git a/shared-module/keypad/__init__.c b/shared-module/keypad/__init__.c index fc41396617..e239c56b61 100644 --- a/shared-module/keypad/__init__.c +++ b/shared-module/keypad/__init__.c @@ -57,12 +57,9 @@ void keypad_tick(void) { } void keypad_reset(void) { - if (MP_STATE_VM(keypad_scanners_linked_list)) { - supervisor_disable_tick(); + while (MP_STATE_VM(keypad_scanners_linked_list)) { + keypad_deregister_scanner(MP_STATE_VM(keypad_scanners_linked_list)); } - - MP_STATE_VM(keypad_scanners_linked_list) = NULL; - keypad_scanners_linked_list_lock = false; } // Register a Keys, KeyMatrix, etc. that will be scanned in the background @@ -71,10 +68,16 @@ void keypad_register_scanner(keypad_scanner_obj_t *scanner) { scanner->next = MP_STATE_VM(keypad_scanners_linked_list); MP_STATE_VM(keypad_scanners_linked_list) = scanner; supervisor_release_lock(&keypad_scanners_linked_list_lock); + + // One more request for ticks. + supervisor_enable_tick(); } // Remove scanner from the list of active scanners. void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) { + // One less request for ticks. + supervisor_disable_tick(); + supervisor_acquire_lock(&keypad_scanners_linked_list_lock); if (MP_STATE_VM(keypad_scanners_linked_list) == scanner) { // Scanner is at the front; splice it out. diff --git a/shared-module/bitbangio/OneWire.c b/shared-module/onewireio/OneWire.c similarity index 85% rename from shared-module/bitbangio/OneWire.c rename to shared-module/onewireio/OneWire.c index 8a73817f37..aeb4dcb00d 100644 --- a/shared-module/bitbangio/OneWire.c +++ b/shared-module/onewireio/OneWire.c @@ -25,24 +25,24 @@ */ #include "common-hal/microcontroller/Pin.h" -#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-bindings/onewireio/OneWire.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/digitalio/DigitalInOut.h" // Durations are taken from here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 -void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t *self, +void common_hal_onewireio_onewire_construct(onewireio_onewire_obj_t *self, const mcu_pin_obj_t *pin) { self->pin.base.type = &digitalio_digitalinout_type; common_hal_digitalio_digitalinout_construct(&self->pin, pin); } -bool shared_module_bitbangio_onewire_deinited(bitbangio_onewire_obj_t *self) { +bool common_hal_onewireio_onewire_deinited(onewireio_onewire_obj_t *self) { return common_hal_digitalio_digitalinout_deinited(&self->pin); } -void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t *self) { - if (shared_module_bitbangio_onewire_deinited(self)) { +void common_hal_onewireio_onewire_deinit(onewireio_onewire_obj_t *self) { + if (common_hal_onewireio_onewire_deinited(self)) { return; } common_hal_digitalio_digitalinout_deinit(&self->pin); @@ -51,7 +51,7 @@ void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t *self) { // We use common_hal_mcu_delay_us(). It should not be dependent on interrupts // to do accurate timekeeping, since we disable interrupts during the delays below. -bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t *self) { +bool common_hal_onewireio_onewire_reset(onewireio_onewire_obj_t *self) { common_hal_mcu_disable_interrupts(); common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); common_hal_mcu_delay_us(480); @@ -63,7 +63,7 @@ bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t *self) { return value; } -bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t *self) { +bool common_hal_onewireio_onewire_read_bit(onewireio_onewire_obj_t *self) { common_hal_mcu_disable_interrupts(); common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); common_hal_mcu_delay_us(6); @@ -78,7 +78,7 @@ bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t *self) { return value; } -void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t *self, +void common_hal_onewireio_onewire_write_bit(onewireio_onewire_obj_t *self, bool bit) { common_hal_mcu_disable_interrupts(); common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); diff --git a/shared-module/bitbangio/OneWire.h b/shared-module/onewireio/OneWire.h similarity index 86% rename from shared-module/bitbangio/OneWire.h rename to shared-module/onewireio/OneWire.h index bc4cb2096f..594478f861 100644 --- a/shared-module/bitbangio/OneWire.h +++ b/shared-module/onewireio/OneWire.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_ONEWIRE_H -#define MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_ONEWIRE_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_ONEWIREIO_ONEWIRE_H +#define MICROPY_INCLUDED_SHARED_MODULE_ONEWIREIO_ONEWIRE_H #include "common-hal/digitalio/DigitalInOut.h" @@ -34,6 +34,6 @@ typedef struct { mp_obj_base_t base; digitalio_digitalinout_obj_t pin; -} bitbangio_onewire_obj_t; +} onewireio_onewire_obj_t; -#endif // MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_ONEWIRE_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_ONEWIREIO_ONEWIRE_H diff --git a/ports/stm/common-hal/busio/OneWire.h b/shared-module/onewireio/__init__.c similarity index 83% rename from ports/stm/common-hal/busio/OneWire.h rename to shared-module/onewireio/__init__.c index 0099593f03..674343c533 100644 --- a/ports/stm/common-hal/busio/OneWire.h +++ b/shared-module/onewireio/__init__.c @@ -24,10 +24,4 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_ONEWIRE_H -#define MICROPY_INCLUDED_STM32_COMMON_HAL_BUSIO_ONEWIRE_H - -// Use bitbangio. -#include "shared-module/busio/OneWire.h" - -#endif // MICROPY_INCLUDED_STM32F_COMMON_HAL_BUSIO_ONEWIRE_H +// Nothing now. diff --git a/shared-module/qrio/QRDecoder.c b/shared-module/qrio/QRDecoder.c new file mode 100644 index 0000000000..227f3b39b4 --- /dev/null +++ b/shared-module/qrio/QRDecoder.c @@ -0,0 +1,137 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/gc.h" +#include "py/objnamedtuple.h" +#include "shared-bindings/qrio/__init__.h" +#include "shared-bindings/qrio/QRInfo.h" +#include "shared-module/qrio/QRDecoder.h" + +void shared_module_qrio_qrdecoder_construct(qrdecoder_qrdecoder_obj_t *self, int width, int height) { + self->quirc = quirc_new(); + quirc_resize(self->quirc, width, height); +} + +int shared_module_qrio_qrdecoder_get_height(qrdecoder_qrdecoder_obj_t *self) { + int height; + quirc_begin(self->quirc, NULL, &height); + return height; +} + +int shared_module_qrio_qrdecoder_get_width(qrdecoder_qrdecoder_obj_t *self) { + int width; + quirc_begin(self->quirc, &width, NULL); + return width; +} +void shared_module_qrio_qrdecoder_set_height(qrdecoder_qrdecoder_obj_t *self, int height) { + if (height != shared_module_qrio_qrdecoder_get_height(self)) { + int width = shared_module_qrio_qrdecoder_get_width(self); + quirc_resize(self->quirc, width, height); + } +} + +void shared_module_qrio_qrdecoder_set_width(qrdecoder_qrdecoder_obj_t *self, int width) { + if (width != shared_module_qrio_qrdecoder_get_width(self)) { + int height = shared_module_qrio_qrdecoder_get_height(self); + quirc_resize(self->quirc, width, height); + } +} + +STATIC mp_obj_t data_type(int type) { + switch (type) { + case QUIRC_ECI_ISO_8859_1: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_1); + case QUIRC_ECI_IBM437: + return MP_OBJ_NEW_QSTR(MP_QSTR_cp437); + case QUIRC_ECI_ISO_8859_2: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_2); + case QUIRC_ECI_ISO_8859_3: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_3); + case QUIRC_ECI_ISO_8859_4: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_4); + case QUIRC_ECI_ISO_8859_5: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_5); + case QUIRC_ECI_ISO_8859_6: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_6); + case QUIRC_ECI_ISO_8859_7: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_7); + case QUIRC_ECI_ISO_8859_8: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_8); + case QUIRC_ECI_ISO_8859_9: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_9); + case QUIRC_ECI_WINDOWS_874: + return MP_OBJ_NEW_QSTR(MP_QSTR_cp874); + case QUIRC_ECI_ISO_8859_13: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_13); + case QUIRC_ECI_ISO_8859_15: + return MP_OBJ_NEW_QSTR(MP_QSTR_iso_8859_hyphen_15); + case QUIRC_ECI_SHIFT_JIS: + return MP_OBJ_NEW_QSTR(MP_QSTR_shift_underscore_jis); + case QUIRC_ECI_UTF_8: + return MP_OBJ_NEW_QSTR(MP_QSTR_utf_hyphen_8); + } + return mp_obj_new_int(type); +} + +mp_obj_t shared_module_qrio_qrdecoder_decode(qrdecoder_qrdecoder_obj_t *self, const mp_buffer_info_t *bufinfo, qrio_pixel_policy_t policy) { + int width, height; + uint8_t *framebuffer = quirc_begin(self->quirc, &width, &height); + uint8_t *src = bufinfo->buf; + + switch (policy) { + case QRIO_EVERY_BYTE: + memcpy(framebuffer, src, width * height); + break; + + case QRIO_ODD_BYTES: + src++; + MP_FALLTHROUGH; + + case QRIO_EVEN_BYTES: + for (int i = 0; i < width * height; i++) { + framebuffer[i] = src[2 * i]; + } + } + quirc_end(self->quirc); + + int count = quirc_count(self->quirc); + mp_obj_t result = mp_obj_new_list(0, NULL); + for (int i = 0; i < count; i++) { + quirc_extract(self->quirc, i, &self->code); + if (quirc_decode(&self->code, &self->data) != QUIRC_SUCCESS) { + continue; + } + mp_obj_t elems[2] = { + mp_obj_new_bytes(self->data.payload, self->data.payload_len), + data_type(self->data.data_type), + }; + mp_obj_t code_obj = namedtuple_make_new((const mp_obj_type_t *)&qrio_qrinfo_type_obj, 2, elems, NULL); + mp_obj_list_append(result, code_obj); + } + return result; +} diff --git a/shared-module/qrio/QRDecoder.h b/shared-module/qrio/QRDecoder.h new file mode 100644 index 0000000000..096dcd2e3f --- /dev/null +++ b/shared-module/qrio/QRDecoder.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" +#include "lib/quirc/lib/quirc.h" +#include "shared-bindings/qrio/PixelPolicy.h" + +typedef struct qrio_qrdecoder_obj { + mp_obj_base_t base; + struct quirc *quirc; + struct quirc_code code; + struct quirc_data data; +} qrdecoder_qrdecoder_obj_t; + +void shared_module_qrio_qrdecoder_construct(qrdecoder_qrdecoder_obj_t *, int width, int height); +int shared_module_qrio_qrdecoder_get_height(qrdecoder_qrdecoder_obj_t *); +int shared_module_qrio_qrdecoder_get_width(qrdecoder_qrdecoder_obj_t *); +void shared_module_qrio_qrdecoder_set_height(qrdecoder_qrdecoder_obj_t *, int height); +void shared_module_qrio_qrdecoder_set_width(qrdecoder_qrdecoder_obj_t *, int width); +mp_obj_t shared_module_qrio_qrdecoder_decode(qrdecoder_qrdecoder_obj_t *, const mp_buffer_info_t *bufinfo, qrio_pixel_policy_t policy); diff --git a/shared-module/qrio/__init__.c b/shared-module/qrio/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/qrio/quirc_alloc.h b/shared-module/qrio/quirc_alloc.h new file mode 100644 index 0000000000..b01fac5bfb --- /dev/null +++ b/shared-module/qrio/quirc_alloc.h @@ -0,0 +1,14 @@ +#pragma once + +#include "py/gc.h" + +#if !MICROPY_GC_CONSERVATIVE_CLEAR +// so that we can implement calloc as m_malloc +#error Requires MICROPY_GC_CONSERVATIVE_CLEAR +#endif + +#define QUIRC_MALLOC(x) gc_alloc((x), 0, false) +#define QUIRC_CALLOC(x,y) gc_alloc((x) * (y), 0, false) +#define QUIRC_FREE(x) gc_free((x)) + +#define QUIRC_SMALL_STACK (1) diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 8e4979ecad..48010aa650 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -46,6 +46,10 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d } size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { + // Make sure the terminal is initialized before we do anything with it. + if (self->tilegrid == NULL) { + return len; + } const byte *i = data; uint16_t start_y = self->cursor_y; while (i < data + len) { @@ -169,5 +173,5 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con } bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) { - return true; + return self->tilegrid != NULL; } diff --git a/shared-module/traceback/__init__.c b/shared-module/traceback/__init__.c new file mode 100644 index 0000000000..a29bd5743f --- /dev/null +++ b/shared-module/traceback/__init__.c @@ -0,0 +1,31 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * 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-module/traceback/__init__.h" + +void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t *print, mp_int_t limit) { + mp_obj_print_exception_with_limit(print, exc, limit); +} diff --git a/shared-module/traceback/__init__.h b/shared-module/traceback/__init__.h new file mode 100644 index 0000000000..73edd07504 --- /dev/null +++ b/shared-module/traceback/__init__.h @@ -0,0 +1,36 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H + +#include "py/objexcept.h" +#include "py/objtraceback.h" + +extern void shared_module_traceback_print_exception(mp_obj_exception_t *exc, + mp_print_t *print, mp_int_t limit); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index ad64070448..e864b08873 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -36,38 +36,39 @@ #include "tusb.h" static const uint8_t keyboard_report_descriptor[] = { - 0x05, 0x01, // 0,1 Usage Page (Generic Desktop Ctrls) - 0x09, 0x06, // 2,3 Usage (Keyboard) - 0xA1, 0x01, // 4,5 Collection (Application) - 0x85, 0xFF, // 6,7 Report ID [SET AT RUNTIME] -#define KEYBOARD_REPORT_ID_INDEX (7) - 0x05, 0x07, // Usage Page (Kbrd/Keypad) - 0x19, 0xE0, // Usage Minimum (0xE0) - 0x29, 0xE7, // Usage Maximum (0xE7) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x75, 0x01, // Report Size (1) - 0x95, 0x08, // Report Count (8) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x19, 0x00, // Usage Minimum (0x00) - 0x29, 0xDD, // Usage Maximum (0xDD) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0xDD, // Logical Maximum (-35) - 0x75, 0x08, // Report Size (8) - 0x95, 0x06, // Report Count (6) - 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x05, 0x08, // Usage Page (LEDs) - 0x19, 0x01, // Usage Minimum (Num Lock) - 0x29, 0x05, // Usage Maximum (Kana) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x75, 0x01, // Report Size (1) - 0x95, 0x05, // Report Count (5) - 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0x95, 0x03, // Report Count (3) - 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0xC0, // End Collection + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x01, // Report ID (1) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0xE0, // Usage Minimum (0xE0) + 0x29, 0xE7, // Usage Maximum (0xE7) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x03, // Report Count (3) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Page (LEDs) + 0x19, 0x01, // Usage Minimum (Num Lock) + 0x29, 0x05, // Usage Maximum (Kana) + 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x95, 0x01, // Report Count (1) + 0x75, 0x05, // Report Size (5) + 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0x00, // Usage Minimum (0x00) + 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection }; const usb_hid_device_obj_t usb_hid_device_keyboard_obj = { @@ -78,20 +79,19 @@ const usb_hid_device_obj_t usb_hid_device_keyboard_obj = { .report_descriptor_length = sizeof(keyboard_report_descriptor), .usage_page = 0x01, .usage = 0x06, - .in_report_length = 8, - .out_report_length = 1, - .report_id_index = KEYBOARD_REPORT_ID_INDEX, - + .num_report_ids = 1, + .report_ids = { 0x01, }, + .in_report_lengths = { 8, 0, 0, 0, 0, 0, }, + .out_report_lengths = { 1, }, }; static const uint8_t mouse_report_descriptor[] = { - 0x05, 0x01, // 0,1 Usage Page (Generic Desktop Ctrls) - 0x09, 0x02, // 2,3 Usage (Mouse) - 0xA1, 0x01, // 4,5 Collection (Application) - 0x09, 0x01, // 6,7 Usage (Pointer) - 0xA1, 0x00, // 8,9 Collection (Physical) - 0x85, 0xFF, // 10, 11 Report ID [SET AT RUNTIME] -#define MOUSE_REPORT_ID_INDEX (11) + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x02, // Usage (Mouse) + 0xA1, 0x01, // Collection (Application) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection (Physical) + 0x85, 0x02, // 10, 11 Report ID (2) 0x05, 0x09, // Usage Page (Button) 0x19, 0x01, // Usage Minimum (0x01) 0x29, 0x05, // Usage Maximum (0x05) @@ -129,17 +129,17 @@ const usb_hid_device_obj_t usb_hid_device_mouse_obj = { .report_descriptor_length = sizeof(mouse_report_descriptor), .usage_page = 0x01, .usage = 0x02, - .in_report_length = 4, - .out_report_length = 0, - .report_id_index = MOUSE_REPORT_ID_INDEX, + .num_report_ids = 1, + .report_ids = { 0x02, }, + .in_report_lengths = { 4, 0, 0, 0, 0, 0, }, + .out_report_lengths = { 0, }, }; static const uint8_t consumer_control_report_descriptor[] = { - 0x05, 0x0C, // 0,1 Usage Page (Consumer) - 0x09, 0x01, // 2,3 Usage (Consumer Control) - 0xA1, 0x01, // 4,5 Collection (Application) - 0x85, 0xFF, // 6,7 Report ID [SET AT RUNTIME] -#define CONSUMER_CONTROL_REPORT_ID_INDEX (7) + 0x05, 0x0C, // Usage Page (Consumer) + 0x09, 0x01, // Usage (Consumer Control) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x03, // Report ID (3) 0x75, 0x10, // Report Size (16) 0x95, 0x01, // Report Count (1) 0x15, 0x01, // Logical Minimum (1) @@ -158,20 +158,46 @@ const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = { .report_descriptor_length = sizeof(consumer_control_report_descriptor), .usage_page = 0x0C, .usage = 0x01, - .in_report_length = 2, - .out_report_length = 0, - .report_id_index = CONSUMER_CONTROL_REPORT_ID_INDEX, + .num_report_ids = 1, + .report_ids = { 0x03 }, + .in_report_lengths = { 2, 0, 0, 0, 0, 0, }, + .out_report_lengths = { 0, }, }; +STATIC size_t get_report_id_idx(usb_hid_device_obj_t *self, size_t report_id) { + for (size_t i = 0; i < self->num_report_ids; i++) { + if (report_id == self->report_ids[i]) { + return i; + } + } + return MAX_REPORT_IDS_PER_DESCRIPTOR; +} + +// See if report_id is used by this device. If it is -1, then return the sole report id used by this device, +// which might be 0 if no report_id was supplied. +uint8_t common_hal_usb_hid_device_validate_report_id(usb_hid_device_obj_t *self, mp_int_t report_id_arg) { + if (report_id_arg == -1 && self->num_report_ids == 1) { + return self->report_ids[0]; + } + if (!(report_id_arg >= 0 && + get_report_id_idx(self, (size_t)report_id_arg) < MAX_REPORT_IDS_PER_DESCRIPTOR)) { + mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_report_id); + } + return (uint8_t)report_id_arg; +} + +void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint8_t usage_page, uint8_t usage, size_t num_report_ids, uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths) { + if (num_report_ids > MAX_REPORT_IDS_PER_DESCRIPTOR) { + mp_raise_ValueError_varg(translate("More than %d report ids not supported"), + MAX_REPORT_IDS_PER_DESCRIPTOR); + } -void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint8_t usage_page, uint8_t usage, uint8_t in_report_length, uint8_t out_report_length, uint8_t report_id_index) { // report buffer pointers are NULL at start, and are created when USB is initialized. - mp_buffer_info_t bufinfo; mp_get_buffer_raise(report_descriptor, &bufinfo, MP_BUFFER_READ); self->report_descriptor_length = bufinfo.len; - // Copy the raw the descriptor bytes into a heap obj. We don't keep the Python descriptor object. + // Copy the raw descriptor bytes into a heap obj. We don't keep the Python descriptor object. uint8_t *descriptor_bytes = gc_alloc(bufinfo.len, false, false); memcpy(descriptor_bytes, bufinfo.buf, bufinfo.len); @@ -179,9 +205,10 @@ void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t re self->usage_page = usage_page; self->usage = usage; - self->in_report_length = in_report_length; - self->out_report_length = out_report_length; - self->report_id_index = report_id_index; + self->num_report_ids = num_report_ids; + memcpy(self->report_ids, report_ids, num_report_ids); + memcpy(self->in_report_lengths, in_report_lengths, num_report_ids); + memcpy(self->out_report_lengths, out_report_lengths, num_report_ids); } uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { @@ -192,9 +219,13 @@ uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { return self->usage; } -void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len) { - if (len != self->in_report_length) { - mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->in_report_length); +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len, uint8_t report_id) { + // report_id and len have already been validated for this device. + size_t id_idx = get_report_id_idx(self, report_id); + + if (len != self->in_report_lengths[id_idx]) { + mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), + self->in_report_lengths[id_idx]); } // Wait until interface is ready, timeout = 2 seconds @@ -207,25 +238,35 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t * mp_raise_msg(&mp_type_OSError, translate("USB busy")); } - memcpy(self->in_report_buffer, report, len); - - if (!tud_hid_report(self->report_id, self->in_report_buffer, len)) { + if (!tud_hid_report(report_id, report, len)) { mp_raise_msg(&mp_type_OSError, translate("USB error")); } } +mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id) { + // report_id has already been validated for this deveice. + size_t id_idx = get_report_id_idx(self, report_id); + return mp_obj_new_bytes(self->out_report_buffers[id_idx], self->out_report_lengths[id_idx]); +} void usb_hid_device_create_report_buffers(usb_hid_device_obj_t *self) { - if (self->in_report_length > 0) { - self->in_report_buffer = gc_alloc(self->in_report_length, false, true /*long-lived*/); - } - if (self->out_report_length > 0) { - self->out_report_buffer = gc_alloc(self->out_report_length, false, true /*long-lived*/); + for (size_t i = 0; i < self->num_report_ids; i++) { + // The IN buffers are used only for tud_hid_get_report_cb(), + // which is an unusual case. Normally we can just pass the data directly with tud_hid_report(). + self->in_report_buffers[i] = + self->in_report_lengths[i] > 0 + ? gc_alloc(self->in_report_lengths[i], false, true /*long-lived*/) + : NULL; + + self->out_report_buffers[i] = + self->out_report_lengths[i] > 0 + ? gc_alloc(self->out_report_lengths[i], false, true /*long-lived*/) + : NULL; } } -// Callbacks invoked when receive Get_Report request through control endpoint +// Callbacks invoked when we received Get_Report request through control endpoint uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) { (void)itf; // only support Input Report @@ -234,11 +275,21 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t } // fill buffer with current report - memcpy(buffer, usb_hid_get_device_with_report_id(report_id)->in_report_buffer, reqlen); - return reqlen; + + usb_hid_device_obj_t *hid_device; + size_t id_idx; + // Find device with this report id, and get the report id index. + if (usb_hid_get_device_with_report_id(report_id, &hid_device, &id_idx)) { + // Make sure buffer exists before trying to copy into it. + if (hid_device->in_report_buffers[id_idx]) { + memcpy(buffer, hid_device->in_report_buffers[id_idx], reqlen); + return reqlen; + } + } + return 0; } -// Callbacks invoked when receive Set_Report request through control endpoint +// Callbacks invoked when we received Set_Report request through control endpoint void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { (void)itf; if (report_type == HID_REPORT_TYPE_INVALID) { @@ -249,9 +300,15 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep return; } - usb_hid_device_obj_t *hid_device = usb_hid_get_device_with_report_id(report_id); - - if (hid_device && hid_device->out_report_length >= bufsize) { - memcpy(hid_device->out_report_buffer, buffer, bufsize); + usb_hid_device_obj_t *hid_device; + size_t id_idx; + // Find device with this report id, and get the report id index. + if (usb_hid_get_device_with_report_id(report_id, &hid_device, &id_idx)) { + // If a report of the correct size has been read, save it in the proper OUT report buffer. + if (hid_device && + hid_device->out_report_buffers[id_idx] && + hid_device->out_report_lengths[id_idx] >= bufsize) { + memcpy(hid_device->out_report_buffers[id_idx], buffer, bufsize); + } } } diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h index db3d8ecf65..a3c523acd5 100644 --- a/shared-module/usb_hid/Device.h +++ b/shared-module/usb_hid/Device.h @@ -32,19 +32,24 @@ #include "py/obj.h" +// The most complicated device currently known of is the head and eye tracker, which requires 5 +// report ids. +// https://usb.org/sites/default/files/hutrr74_-_usage_page_for_head_and_eye_trackers_0.pdf +#define MAX_REPORT_IDS_PER_DESCRIPTOR (6) + typedef struct { mp_obj_base_t base; // Python buffer object whose contents are the descriptor. const uint8_t *report_descriptor; - uint8_t *in_report_buffer; - uint8_t *out_report_buffer; - uint16_t report_id_index; + uint8_t *in_report_buffers[MAX_REPORT_IDS_PER_DESCRIPTOR]; + uint8_t *out_report_buffers[MAX_REPORT_IDS_PER_DESCRIPTOR]; uint16_t report_descriptor_length; + uint8_t report_ids[MAX_REPORT_IDS_PER_DESCRIPTOR]; + uint8_t in_report_lengths[MAX_REPORT_IDS_PER_DESCRIPTOR]; + uint8_t out_report_lengths[MAX_REPORT_IDS_PER_DESCRIPTOR]; uint8_t usage_page; uint8_t usage; - uint8_t report_id; - uint8_t in_report_length; - uint8_t out_report_length; + uint8_t num_report_ids; } usb_hid_device_obj_t; extern const usb_hid_device_obj_t usb_hid_device_keyboard_obj; diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index 81a62c8eb3..e61d01cc16 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -197,10 +197,6 @@ size_t usb_hid_report_descriptor_length(void) { total_hid_report_descriptor_length += hid_devices[i].report_descriptor_length; } - // Don't need space for a report id if there's only one device. - if (num_hid_devices == 1) { - total_hid_report_descriptor_length -= 2; - } return total_hid_report_descriptor_length; } @@ -215,24 +211,11 @@ void usb_hid_build_report_descriptor(uint8_t *report_descriptor_space, size_t re for (mp_int_t i = 0; i < num_hid_devices; i++) { usb_hid_device_obj_t *device = &hid_devices[i]; // Copy the report descriptor for this device. - if (num_hid_devices == 1) { - // There's only one device, so it shouldn't have a report ID. - // Copy the descriptor, but splice out the report id indicator and value (2 bytes). - memcpy(report_descriptor_start, device->report_descriptor, device->report_id_index - 1); - report_descriptor_start += device->report_id_index - 1; - memcpy(report_descriptor_start, device->report_descriptor + device->report_id_index + 1, - device->report_descriptor_length - device->report_id_index - 1); - } else { - // Copy the whole descriptor and fill in the report id. - memcpy(report_descriptor_start, device->report_descriptor, device->report_descriptor_length); - report_descriptor_start[device->report_id_index] = i + 1; + memcpy(report_descriptor_start, device->report_descriptor, device->report_descriptor_length); - // Remember the report id that was assigned. - device->report_id = i + 1; + // Advance to the next free chunk for the next report descriptor.x + report_descriptor_start += device->report_descriptor_length; - // Advance to the next free chunk for the next report descriptor.x - report_descriptor_start += device->report_descriptor_length; - } // Clear the heap pointer to the bytes of the descriptor. // We don't need it any more and it will get lost when the heap goes away. device->report_descriptor = NULL; @@ -260,24 +243,33 @@ void usb_hid_gc_collect(void) { gc_collect_ptr(hid_devices_tuple); // Mark possible heap pointers in the static device list as in use. - for (mp_int_t i = 0; i < num_hid_devices; i++) { + for (mp_int_t device_idx = 0; device_idx < num_hid_devices; device_idx++) { + // Cast away the const for .report_descriptor. It could be in flash or on the heap. // Constant report descriptors must be const so that they are used directly from flash // and not copied into RAM. - gc_collect_ptr((void *)hid_devices[i].report_descriptor); - gc_collect_ptr(hid_devices[i].in_report_buffer); - gc_collect_ptr(hid_devices[i].out_report_buffer); + gc_collect_ptr((void *)hid_devices[device_idx].report_descriptor); + + // Collect all the report buffers for this device. + for (size_t id_idx = 0; id_idx < hid_devices[device_idx].num_report_ids; id_idx++) { + gc_collect_ptr(hid_devices[id_idx].in_report_buffers[id_idx]); + gc_collect_ptr(hid_devices[id_idx].out_report_buffers[id_idx]); + } } } -usb_hid_device_obj_t *usb_hid_get_device_with_report_id(uint8_t report_id) { - for (uint8_t i = 0; i < num_hid_devices; i++) { - usb_hid_device_obj_t *device = &hid_devices[i]; - if (device->report_id == report_id) { - return &hid_devices[i]; +bool usb_hid_get_device_with_report_id(uint8_t report_id, usb_hid_device_obj_t **device_out, size_t *id_idx_out) { + for (uint8_t device_idx = 0; device_idx < num_hid_devices; device_idx++) { + usb_hid_device_obj_t *device = &hid_devices[device_idx]; + for (size_t id_idx = 0; id_idx < device->num_report_ids; id_idx++) { + if (device->report_ids[id_idx] == report_id) { + *device_out = device; + *id_idx_out = id_idx; + return true; + } } } - return NULL; + return false; } // Invoked when GET HID REPORT DESCRIPTOR is received. diff --git a/shared-module/usb_hid/__init__.h b/shared-module/usb_hid/__init__.h index 5069effd3d..6d85b50e9f 100644 --- a/shared-module/usb_hid/__init__.h +++ b/shared-module/usb_hid/__init__.h @@ -44,7 +44,7 @@ size_t usb_hid_report_descriptor_length(void); void usb_hid_build_report_descriptor(uint8_t *report_descriptor_space, size_t report_descriptor_length); void usb_hid_save_report_descriptor(uint8_t *report_descriptor_space, size_t report_descriptor_length); -usb_hid_device_obj_t *usb_hid_get_device_with_report_id(uint8_t report_id); +bool usb_hid_get_device_with_report_id(uint8_t report_id, usb_hid_device_obj_t **device_out, size_t *id_idx_out); void usb_hid_gc_collect(void); diff --git a/shared-module/vectorio/Circle.c b/shared-module/vectorio/Circle.c index 9c74580650..6b4c441620 100644 --- a/shared-module/vectorio/Circle.c +++ b/shared-module/vectorio/Circle.c @@ -59,3 +59,8 @@ void common_hal_vectorio_circle_set_radius(void *obj, int16_t radius) { self->on_dirty.event(self->on_dirty.obj); } } + +mp_obj_t common_hal_vectorio_circle_get_draw_protocol(void *circle) { + vectorio_circle_t *self = circle; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Circle.h b/shared-module/vectorio/Circle.h index d6a77b1667..106bca6a71 100644 --- a/shared-module/vectorio/Circle.h +++ b/shared-module/vectorio/Circle.h @@ -11,6 +11,7 @@ typedef struct { mp_obj_base_t base; uint16_t radius; vectorio_event_t on_dirty; + mp_obj_t draw_protocol_instance; } vectorio_circle_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_CIRCLE_H diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c index 00af1e0d7e..f7199c7f83 100644 --- a/shared-module/vectorio/Polygon.c +++ b/shared-module/vectorio/Polygon.c @@ -1,4 +1,3 @@ - #include "shared-module/vectorio/__init__.h" #include "shared-bindings/vectorio/Polygon.h" #include "shared-module/displayio/area.h" @@ -11,7 +10,7 @@ #define VECTORIO_POLYGON_DEBUG(...) (void)0 -// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Converts a list of points tuples to a flat list of ints for speedier internal use. @@ -31,12 +30,12 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple VECTORIO_POLYGON_DEBUG("free(%d), ", sizeof(self->points_list)); gc_free(self->points_list); } - self->points_list = gc_alloc(2 * len * sizeof(int), false, false); - VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(int)); + self->points_list = gc_alloc(2 * len * sizeof(uint16_t), false, false); + VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(uint16_t)); } self->len = 2 * len; - for (size_t i = 0; i < len; ++i) { + for (uint16_t i = 0; i < len; ++i) { size_t tuple_len = 0; mp_obj_t *tuple_items; mp_obj_tuple_get(items[i], &tuple_len, &tuple_items); @@ -44,14 +43,19 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple if (tuple_len != 2) { mp_raise_ValueError_varg(translate("%q must be a tuple of length 2"), MP_QSTR_point); } - if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &self->points_list[2 * i ]) - || !mp_obj_get_int_maybe(tuple_items[ 1 ], &self->points_list[2 * i + 1]) + mp_int_t x; + mp_int_t y; + if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) + || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y) + || x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX ) { - self->len = 0; gc_free(self->points_list); self->points_list = NULL; mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + self->len = 0; } + self->points_list[2 * i ] = (int16_t)x; + self->points_list[2 * i + 1] = (int16_t)y; } } @@ -69,16 +73,23 @@ void common_hal_vectorio_polygon_construct(vectorio_polygon_t *self, mp_obj_t po mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self) { VECTORIO_POLYGON_DEBUG("%p common_hal_vectorio_polygon_get_points {len: %d, points_list: %p}\n", self, self->len, self->points_list); - mp_obj_t list = mp_obj_new_list(self->len / 2, NULL); + mp_obj_list_t *list = MP_OBJ_TO_PTR(mp_obj_new_list(0, NULL)); + + VECTORIO_POLYGON_DEBUG(" >points\n"); + for (uint16_t i = 0; i < self->len; i += 2) { + VECTORIO_POLYGON_DEBUG(" (%4d, %4d)\n", self->points_list[i], self->points_list[i + 1]); + + mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + pair->items[0] = mp_obj_new_int((mp_int_t)self->points_list[i ]); + pair->items[1] = mp_obj_new_int((mp_int_t)self->points_list[i + 1]); - for (size_t i = 0; i < self->len; i += 2) { - mp_obj_t tuple[] = { mp_obj_new_int(self->points_list[i]), mp_obj_new_int(self->points_list[i + 1]) }; mp_obj_list_append( list, - mp_obj_new_tuple(2, tuple) + pair ); } - return list; + VECTORIO_POLYGON_DEBUG(" x1 = SHRT_MAX; area->y1 = SHRT_MAX; area->x2 = SHRT_MIN; area->y2 = SHRT_MIN; - for (size_t i = 0; i < self->len; ++i) { - int x = self->points_list[i]; + for (uint16_t i = 0; i < self->len; ++i) { + int16_t x = self->points_list[i]; ++i; - int y = self->points_list[i]; - if (x <= area->x1) { - area->x1 = x - 1; + int16_t y = self->points_list[i]; + if (x < area->x1) { + VECTORIO_POLYGON_DEBUG(" x1: %d\n", x); + area->x1 = x; } - if (y <= area->y1) { - area->y1 = y - 1; + if (y < area->y1) { + VECTORIO_POLYGON_DEBUG(" y1: %d\n", y); + area->y1 = y; } - if (x >= area->x2) { - area->x2 = x + 1; + if (x > area->x2) { + VECTORIO_POLYGON_DEBUG(" x2: %d\n", x); + area->x2 = x; } - if (y >= area->y2) { - area->y2 = y + 1; + if (y > area->y2) { + VECTORIO_POLYGON_DEBUG(" y2: %d\n", y); + area->y2 = y; } } } @@ -127,7 +143,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area) // <0 if the point is to the left of the line vector // 0 if the point is on the line // >0 if the point is to the right of the line vector -__attribute__((always_inline)) static inline int line_side(mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, int16_t px, int16_t py) { +__attribute__((always_inline)) static inline int line_side(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t px, int16_t py) { return (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1); } @@ -141,14 +157,14 @@ uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y) return 0; } - int winding_number = 0; - int x1 = self->points_list[0]; - int y1 = self->points_list[1]; - for (size_t i = 2; i <= self->len + 1; ++i) { + int16_t winding_number = 0; + int16_t x1 = self->points_list[0]; + int16_t y1 = self->points_list[1]; + for (uint16_t i = 2; i <= self->len + 1; ++i) { VECTORIO_POLYGON_DEBUG(" {(%3d, %3d),", x1, y1); - int x2 = self->points_list[i % self->len]; + int16_t x2 = self->points_list[i % self->len]; ++i; - int y2 = self->points_list[i % self->len]; + int16_t y2 = self->points_list[i % self->len]; VECTORIO_POLYGON_DEBUG(" (%3d, %3d)}\n", x2, y2); if (y1 <= y) { if (y2 > y && line_side(x1, y1, x2, y2, x, y) < 0) { @@ -167,3 +183,8 @@ uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y) } return winding_number == 0 ? 0 : 1; } + +mp_obj_t common_hal_vectorio_polygon_get_draw_protocol(void *polygon) { + vectorio_polygon_t *self = polygon; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Polygon.h b/shared-module/vectorio/Polygon.h index 70de9036d7..e1d94f9f97 100644 --- a/shared-module/vectorio/Polygon.h +++ b/shared-module/vectorio/Polygon.h @@ -9,9 +9,10 @@ typedef struct { mp_obj_base_t base; // An int array[ x, y, ... ] - int *points_list; - size_t len; + int16_t *points_list; + uint16_t len; vectorio_event_t on_dirty; + mp_obj_t draw_protocol_instance; } vectorio_polygon_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_POLYGON_H diff --git a/shared-module/vectorio/Rectangle.c b/shared-module/vectorio/Rectangle.c index 56be5ebb5e..2471daa608 100644 --- a/shared-module/vectorio/Rectangle.c +++ b/shared-module/vectorio/Rectangle.c @@ -12,10 +12,10 @@ void common_hal_vectorio_rectangle_construct(vectorio_rectangle_t *self, uint32_ uint32_t common_hal_vectorio_rectangle_get_pixel(void *obj, int16_t x, int16_t y) { vectorio_rectangle_t *self = obj; - if (x < 0 || x >= self->width || y >= self->height || y < 0) { - return 0; + if (x >= 0 && y >= 0 && x < self->width && y < self->height) { + return 1; } - return 1; + return 0; } @@ -32,3 +32,8 @@ uint32_t common_hal_vectorio_rectangle_get_height(void *rectangle) { vectorio_rectangle_t *self = rectangle; return self->height; } + +mp_obj_t common_hal_vectorio_rectangle_get_draw_protocol(void *rectangle) { + vectorio_rectangle_t *self = rectangle; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Rectangle.h b/shared-module/vectorio/Rectangle.h index 56342a6d76..e3cfbb2676 100644 --- a/shared-module/vectorio/Rectangle.h +++ b/shared-module/vectorio/Rectangle.h @@ -9,6 +9,7 @@ typedef struct { mp_obj_base_t base; uint16_t width; uint16_t height; + mp_obj_t draw_protocol_instance; } vectorio_rectangle_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_RECTANGLE_H diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index f0b6a725c1..9d0279cf14 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -15,16 +15,51 @@ // Lifecycle actions. #define VECTORIO_SHAPE_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables -// #define VECTORIO_PERF(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_PERF(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Really verbose. #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + +#define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" +#define U32_TO_BINARY(u32) \ + (u32 & 0x80000000 ? '1' : '0'), \ + (u32 & 0x40000000 ? '1' : '0'), \ + (u32 & 0x20000000 ? '1' : '0'), \ + (u32 & 0x10000000 ? '1' : '0'), \ + (u32 & 0x8000000 ? '1' : '0'), \ + (u32 & 0x4000000 ? '1' : '0'), \ + (u32 & 0x2000000 ? '1' : '0'), \ + (u32 & 0x1000000 ? '1' : '0'), \ + (u32 & 0x800000 ? '1' : '0'), \ + (u32 & 0x400000 ? '1' : '0'), \ + (u32 & 0x200000 ? '1' : '0'), \ + (u32 & 0x100000 ? '1' : '0'), \ + (u32 & 0x80000 ? '1' : '0'), \ + (u32 & 0x40000 ? '1' : '0'), \ + (u32 & 0x20000 ? '1' : '0'), \ + (u32 & 0x10000 ? '1' : '0'), \ + (u32 & 0x8000 ? '1' : '0'), \ + (u32 & 0x4000 ? '1' : '0'), \ + (u32 & 0x2000 ? '1' : '0'), \ + (u32 & 0x1000 ? '1' : '0'), \ + (u32 & 0x800 ? '1' : '0'), \ + (u32 & 0x400 ? '1' : '0'), \ + (u32 & 0x200 ? '1' : '0'), \ + (u32 & 0x100 ? '1' : '0'), \ + (u32 & 0x80 ? '1' : '0'), \ + (u32 & 0x40 ? '1' : '0'), \ + (u32 & 0x20 ? '1' : '0'), \ + (u32 & 0x10 ? '1' : '0'), \ + (u32 & 0x8 ? '1' : '0'), \ + (u32 & 0x4 ? '1' : '0'), \ + (u32 & 0x2 ? '1' : '0'), \ + (u32 & 0x1 ? '1' : '0') inline __attribute__((always_inline)) @@ -32,55 +67,98 @@ static int32_t max(int32_t a, int32_t b) { return a > b ? a : b; } +inline __attribute__((always_inline)) +static uint32_t min(uint32_t a, uint32_t b) { + return a < b ? a : b; +} + +inline __attribute__((always_inline)) +static void area_transpose(displayio_area_t *to_transpose) { + int16_t swap = to_transpose->y1; + to_transpose->y1 = to_transpose->x1; + to_transpose->x1 = swap; + swap = to_transpose->y2; + to_transpose->y2 = to_transpose->x2; + to_transpose->x2 = swap; +} inline __attribute__((always_inline)) static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { - VECTORIO_SHAPE_DEBUG("%p get_screen_area tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", self, + VECTORIO_SHAPE_DEBUG("%p get_screen_area (%3d,%3d) tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", self, self->x, self->y, self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy ); self->ishape.get_area(self->ishape.shape, out_area); VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", out_area->x1, out_area->y1, out_area->x2, out_area->y2); + + int16_t x; + int16_t y; if (self->absolute_transform->transpose_xy) { - int16_t swap = out_area->x1; - out_area->x1 = (out_area->y1 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y1 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; - swap = out_area->x2; - out_area->x2 = (out_area->y2 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y2 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; + x = self->absolute_transform->x + self->absolute_transform->dx * self->y; + y = self->absolute_transform->y + self->absolute_transform->dy * self->x; + if (self->absolute_transform->dx < 1) { + out_area->y1 = out_area->y1 * -1 + 1; + out_area->y2 = out_area->y2 * -1 + 1; + } + if (self->absolute_transform->dy < 1) { + out_area->x1 = out_area->x1 * -1 + 1; + out_area->x2 = out_area->x2 * -1 + 1; + } + area_transpose(out_area); } else { - out_area->x1 = (out_area->x1 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y1 = (out_area->y1 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; - out_area->x2 = (out_area->x2 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y2 = (out_area->y2 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; + x = self->absolute_transform->x + self->absolute_transform->dx * self->x; + y = self->absolute_transform->y + self->absolute_transform->dy * self->y; + + if (self->absolute_transform->dx < 1) { + out_area->x1 = out_area->x1 * -1 + 1; + out_area->x2 = out_area->x2 * -1 + 1; + } + if (self->absolute_transform->dy < 1) { + out_area->y1 = out_area->y1 * -1 + 1; + out_area->y2 = out_area->y2 * -1 + 1; + } } - // We might have mirrored due to dx displayio_area_canon(out_area); + displayio_area_shift(out_area, x, y); + VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2); } // For use by Group to know where it needs to redraw on layer removal. bool vectorio_vector_shape_get_dirty_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { - displayio_area_copy(&self->ephemeral_dirty_area, out_area); + out_area->x1 = out_area->x2; + displayio_area_union( + &self->ephemeral_dirty_area, + &self->current_area, + out_area + ); return true; // For now just always redraw. } -// This must be invoked each time a shape changes its position or its shape in any way. +// This must be invoked after each time a shape changes its position, shape or appearance in any way. void common_hal_vectorio_vector_shape_set_dirty(void *vector_shape) { vectorio_vector_shape_t *self = vector_shape; // In screen space. Need to offset the shape space. displayio_area_t current_area; _get_screen_area(self, ¤t_area); - VECTORIO_SHAPE_DEBUG("%p shape_dirty current:{(%3d,%3d), (%3d,%3d)} dirty:{(%3d,%3d), (%3d,%3d)}", + VECTORIO_SHAPE_DEBUG("%p shape_dirty new:{(%3d,%3d), (%3d,%3d)} dirty:{(%3d,%3d), (%3d,%3d)}", self, current_area.x1, current_area.y1, current_area.x2, current_area.y2, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - self->dirty = true; - // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish, - displayio_area_union(&self->ephemeral_dirty_area, ¤t_area, &self->ephemeral_dirty_area); - VECTORIO_SHAPE_DEBUG(" -> expanded:{(%3d,%3d), (%3d,%3d)}\n", self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + + bool moved = !displayio_area_equal(¤t_area, &self->current_area); + if (moved) { + displayio_area_union(&self->current_area, &self->ephemeral_dirty_area, &self->ephemeral_dirty_area); + VECTORIO_SHAPE_DEBUG(" stale:{(%3d,%3d), (%3d,%3d)} -> expanded:{(%3d,%3d), (%3d,%3d)}\n", + self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + + // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish. + displayio_area_copy(¤t_area, &self->current_area); + } + self->current_area_dirty = true; } @@ -92,10 +170,11 @@ void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, self->y = y; self->pixel_shader = pixel_shader; self->ishape = ishape; - self->dirty = true; self->absolute_transform = &null_transform; // Critical to have a valid transform before getting screen area. - _get_screen_area(self, &self->ephemeral_dirty_area); + self->ephemeral_dirty_area.x1 = self->ephemeral_dirty_area.x2; // Cheat to set area to 0 self->ephemeral_dirty_area.next = NULL; + self->current_area_dirty = true; + _get_screen_area(self, &self->current_area); } @@ -130,6 +209,37 @@ void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_in common_hal_vectorio_vector_shape_set_dirty(self); } +mp_obj_tuple_t *common_hal_vectorio_vector_shape_get_location(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_location\n", self); + mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + pair->items[0] = mp_obj_new_int((mp_int_t)self->x); + pair->items[1] = mp_obj_new_int((mp_int_t)self->y); + return pair; +} + + +void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self, mp_obj_t xy) { + VECTORIO_SHAPE_DEBUG("%p set_location\n", self); + size_t tuple_len = 0; + mp_obj_t *tuple_items; + mp_obj_tuple_get(xy, &tuple_len, &tuple_items); + if (tuple_len != 2) { + mp_raise_TypeError_varg(translate("(x,y) integers required")); + } + + mp_int_t x; + mp_int_t y; + if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) + || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y) + || x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX + ) { + mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + } + self->x = (int16_t)x; + self->y = (int16_t)y; + common_hal_vectorio_vector_shape_set_dirty(self); +} + mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self) { VECTORIO_SHAPE_DEBUG("%p get_pixel_shader\n", self); @@ -153,13 +263,12 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ uint64_t start = common_hal_time_monotonic_ns(); uint64_t pixel_time = 0; #endif - displayio_area_t overlap; - VECTORIO_SHAPE_DEBUG("%p fill_area dirty:%d fill: {(%5d,%5d), (%5d,%5d)} dirty: {(%5d,%5d), (%5d,%5d)}", - self, self->dirty, - area->x1, area->y1, area->x2, area->y2, - self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2 + VECTORIO_SHAPE_DEBUG("%p fill_area: fill: {(%5d,%5d), (%5d,%5d)}", + self, + area->x1, area->y1, area->x2, area->y2 ); - if (!displayio_area_compute_overlap(area, &self->ephemeral_dirty_area, &overlap)) { + displayio_area_t overlap; + if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) { VECTORIO_SHAPE_DEBUG(" no overlap\n"); return false; } @@ -168,27 +277,35 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ bool full_coverage = displayio_area_equal(area, &overlap); uint8_t pixels_per_byte = 8 / colorspace->depth; + VECTORIO_SHAPE_DEBUG(" xy:(%3d %3d) tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", + self->x, self->y, + self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, + self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy + ); - uint32_t linestride_px = displayio_area_width(area); - uint32_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; - uint32_t column_dirty_offset_px = overlap.x1 - area->x1; + uint16_t linestride_px = displayio_area_width(area); + uint16_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; + uint16_t column_dirty_offset_px = overlap.x1 - area->x1; VECTORIO_SHAPE_DEBUG(", linestride:%3d line_offset:%3d col_offset:%3d depth:%2d ppb:%2d shape:%s", linestride_px, line_dirty_offset_px, column_dirty_offset_px, colorspace->depth, pixels_per_byte, mp_obj_get_type_str(self->ishape.shape)); displayio_input_pixel_t input_pixel; displayio_output_pixel_t output_pixel; - uint32_t mask_start_px = line_dirty_offset_px; + displayio_area_t shape_area; + self->ishape.get_area(self->ishape.shape, &shape_area); + + uint16_t mask_start_px = line_dirty_offset_px; for (input_pixel.y = overlap.y1; input_pixel.y < overlap.y2; ++input_pixel.y) { mask_start_px += column_dirty_offset_px; for (input_pixel.x = overlap.x1; input_pixel.x < overlap.x2; ++input_pixel.x) { // Check the mask first to see if the pixel has already been set. - uint32_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); + uint16_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); uint32_t *mask_doubleword = &(mask[pixel_index / 32]); uint8_t mask_bit = pixel_index % 32; - VECTORIO_SHAPE_PIXEL_DEBUG("%p pixel_index: %5u mask_bit: %2u", self, pixel_index, mask_bit); + VECTORIO_SHAPE_PIXEL_DEBUG("\n%p pixel_index: %5u mask_bit: %2u mask: "U32_TO_BINARY_FMT, self, pixel_index, mask_bit, U32_TO_BINARY(*mask_doubleword)); if ((*mask_doubleword & (1u << mask_bit)) != 0) { - VECTORIO_SHAPE_PIXEL_DEBUG(" masked\n"); + VECTORIO_SHAPE_PIXEL_DEBUG(" masked"); continue; } output_pixel.pixel = 0; @@ -197,12 +314,39 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ int16_t pixel_to_get_x; int16_t pixel_to_get_y; if (self->absolute_transform->transpose_xy) { - pixel_to_get_x = (input_pixel.y - self->absolute_transform->dy * self->x - self->absolute_transform->y) / self->absolute_transform->dy; - pixel_to_get_y = (input_pixel.x - self->absolute_transform->dx * self->y - self->absolute_transform->x) / self->absolute_transform->dx; + pixel_to_get_x = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->x; + pixel_to_get_y = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->y; + + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + if (self->absolute_transform->dx < 1) { + pixel_to_get_y *= -1; + } + if (self->absolute_transform->dy < 1) { + pixel_to_get_x *= -1; + } + VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); } else { - pixel_to_get_x = (input_pixel.x - self->absolute_transform->dx * self->x - self->absolute_transform->x) / self->absolute_transform->dx; - pixel_to_get_y = (input_pixel.y - self->absolute_transform->dy * self->y - self->absolute_transform->y) / self->absolute_transform->dy; + pixel_to_get_x = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->x; + pixel_to_get_y = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->y; + + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + if (self->absolute_transform->dx < 1) { + pixel_to_get_x *= -1; + } + if (self->absolute_transform->dy < 1) { + pixel_to_get_y *= -1; + } + VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + + // It's mirrored via dx. Maybe we need to add support for also separately mirroring? + // if (self->absolute_transform->mirror_x) { + // pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x - shape_area.x1) + shape_area.x1 - 1; + // } + // if (self->absolute_transform->mirror_y) { + // pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y - shape_area.y1) + +shape_area.y1 - 1; + // } } + VECTORIO_SHAPE_PIXEL_DEBUG(" get_pixel %p (%3d, %3d) -> ( %3d, %3d )", self->ishape.shape, input_pixel.x, input_pixel.y, pixel_to_get_x, pixel_to_get_y); #ifdef VECTORIO_PERF uint64_t pre_pixel = common_hal_time_monotonic_ns(); @@ -214,39 +358,50 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ #endif VECTORIO_SHAPE_PIXEL_DEBUG(" -> %d", input_pixel.pixel); - output_pixel.opaque = true; - if (self->pixel_shader == mp_const_none) { - output_pixel.pixel = input_pixel.pixel; - } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { - output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); - } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { - displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); - } - if (!output_pixel.opaque) { - VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n"); + // vectorio shapes use 0 to mean "area is not covered." + // We can skip all the rest of the work for this pixel if it's not currently covered by the shape. + if (input_pixel.pixel == 0) { + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)"); full_coverage = false; } else { + // Pixel is not transparent. Let's pull the pixel value index down to 0-base for more error-resistant palettes. + input_pixel.pixel -= 1; + output_pixel.opaque = true; + + if (self->pixel_shader == mp_const_none) { + output_pixel.pixel = input_pixel.pixel; + } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); + } + + // We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily. + if (!output_pixel.opaque) { + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)"); + full_coverage = false; + } + *mask_doubleword |= 1u << mask_bit; if (colorspace->depth == 16) { - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16", output_pixel.pixel); *(((uint16_t *)buffer) + pixel_index) = output_pixel.pixel; } else if (colorspace->depth == 8) { - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %02x 8\n", output_pixel.pixel); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %02x 8", output_pixel.pixel); *(((uint8_t *)buffer) + pixel_index) = output_pixel.pixel; } else if (colorspace->depth < 8) { // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). if (!colorspace->pixels_in_byte_share_row) { - uint16_t width = linestride_px; - uint16_t row = pixel_index / width; - uint16_t col = pixel_index % width; - pixel_index = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte; + uint16_t row = pixel_index / linestride_px; + uint16_t col = pixel_index % linestride_px; + pixel_index = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * linestride_px + row % pixels_per_byte; } uint8_t shift = (pixel_index % pixels_per_byte) * colorspace->depth; if (colorspace->reverse_pixels_in_byte) { // Reverse the shift by subtracting it from the leftmost shift. shift = (pixels_per_byte - 1) * colorspace->depth - shift; } - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %2d %d\n", output_pixel.pixel, colorspace->depth); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %2d %d", output_pixel.pixel, colorspace->depth); ((uint8_t *)buffer)[pixel_index / pixels_per_byte] |= output_pixel.pixel << shift; } } @@ -265,20 +420,23 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ (double)(pixel_time / 1000.0 / pixels) ); #endif - VECTORIO_SHAPE_DEBUG(" -> pixels:%4d\n"); + VECTORIO_SHAPE_DEBUG(" -> pixels:%4d\n", (overlap.x2 - overlap.x1) * (overlap.y2 - overlap.y1)); return full_coverage; } void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { - if (!self->dirty) { + if (displayio_area_empty(&self->ephemeral_dirty_area) && !self->current_area_dirty) { return; } VECTORIO_SHAPE_DEBUG("%p finish_refresh was:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - self->dirty = false; - // Reset dirty area tracking to current footprint - _get_screen_area(self, &self->ephemeral_dirty_area); + // Reset dirty area to nothing + self->ephemeral_dirty_area.x1 = self->ephemeral_dirty_area.x2; // Cheat to set area to empty self->ephemeral_dirty_area.next = NULL; + + self->current_area_dirty = false; // We don't clear current area so we can remember what to clean up if we move + self->current_area.next = NULL; + VECTORIO_SHAPE_DEBUG("%p finish_refresh now:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { @@ -291,16 +449,55 @@ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { // Assembles a singly linked list of dirty areas from all components on the display. displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail) { - if (self->dirty + if (self->current_area_dirty || (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) ) { - VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty:%d {(%3d,%3d), (%3d,%3d)}", self, self->dirty, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - common_hal_vectorio_vector_shape_set_dirty(self); - // vector.add_to_head + if (!displayio_area_empty(&self->ephemeral_dirty_area)) { + // Both are dirty, check if we should combine the areas or draw separately + // Draws as few pixels as possible both when animations move short distances and large distances. + // The display core implementation currently doesn't combine areas to reduce redrawing of masked areas. If it does, + // this could be simplified to just return the 2 possibly overlapping areas. + displayio_area_t area_swap; + displayio_area_compute_overlap(&self->ephemeral_dirty_area, &self->current_area, &area_swap); + uint32_t overlap_size = displayio_area_size(&area_swap); + displayio_area_union(&self->ephemeral_dirty_area, &self->current_area, &area_swap); // Leave area_swap as the union area for later. + uint32_t union_size = displayio_area_size(&area_swap); + uint32_t current_size = displayio_area_size(&self->current_area); + uint32_t dirty_size = displayio_area_size(&self->ephemeral_dirty_area); + + VECTORIO_SHAPE_DEBUG("%p get_refresh_area: dirty{(%3d,%3d), (%3d,%3d)} + current{(%3d,%3d), (%3d,%3d)} = union{(%3d,%3d), (%3d,%3d)}: union%d - dirty%d - curr%d + overlap%d = excluded%d : ", self, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2, + self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, + area_swap.x1, area_swap.y1, area_swap.x2, area_swap.y2, + union_size, dirty_size, current_size, overlap_size, (int32_t)union_size - dirty_size - current_size + overlap_size + ); + + if ((int32_t)union_size - dirty_size - current_size + overlap_size <= min(dirty_size, current_size)) { + // The excluded / non-overlapping area from the disjoint dirty and current areas is smaller + // than the smallest area we need to draw. Redrawing the overlapping area would cost more + // than just drawing the union disjoint area once. + VECTORIO_SHAPE_DEBUG("combining to take disjoint area\n"); + displayio_area_copy(&area_swap, &self->ephemeral_dirty_area); + } else { + // The excluded area between the 2 dirty areas is larger than the smallest dirty area. It would be + // more costly to combine these areas than possibly redraw some overlap. + VECTORIO_SHAPE_DEBUG("excluded area too large, drawing separate area\n"); + self->current_area.next = tail; + tail = &self->current_area; + } + + self->ephemeral_dirty_area.next = tail; + tail = &self->ephemeral_dirty_area; + } else { + self->current_area.next = tail; + tail = &self->current_area; + VECTORIO_SHAPE_DEBUG("%p get_refresh_area: redrawing current: {(%3d,%3d), (%3d,%3d)}\n", self, self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); + } + } else if (!displayio_area_empty(&self->ephemeral_dirty_area)) { self->ephemeral_dirty_area.next = tail; - VECTORIO_SHAPE_DEBUG(" this_area: %p next: %p after: %p\n", &self->ephemeral_dirty_area, tail, tail == NULL ? NULL : tail->next); - return &self->ephemeral_dirty_area; + tail = &self->ephemeral_dirty_area; + VECTORIO_SHAPE_DEBUG("%p get_refresh_area redrawing dirty: {(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); } return tail; } diff --git a/shared-module/vectorio/VectorShape.h b/shared-module/vectorio/VectorShape.h index 1896c72d6e..fdbae964a8 100644 --- a/shared-module/vectorio/VectorShape.h +++ b/shared-module/vectorio/VectorShape.h @@ -31,11 +31,12 @@ typedef struct { int16_t x; int16_t y; displayio_buffer_transform_t *absolute_transform; - bool dirty; // True if we need to draw // Tracks current shape footprint and expands outward as the shape dirties and changes. // This is suboptimal if you move your shape far. Could add more state to only redraw // exactly what we left behind. displayio_area_t ephemeral_dirty_area; + displayio_area_t current_area; + bool current_area_dirty; } vectorio_vector_shape_t; displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail); diff --git a/supervisor/shared/bluetooth/bluetooth.c b/supervisor/shared/bluetooth/bluetooth.c index ade20a9f07..9b1a775f53 100644 --- a/supervisor/shared/bluetooth/bluetooth.c +++ b/supervisor/shared/bluetooth/bluetooth.c @@ -56,7 +56,7 @@ // This standard advertisement advertises the CircuitPython editing service and a CIRCUITPY short name. const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags - 0x02, 0x0a, 0xd8, // 3-5 TX power level -40 + 0x02, 0x0a, 0xec, // 3-5 TX power level -20 #if CIRCUITPY_BLE_FILE_SERVICE 0x03, 0x02, 0xbb, 0xfe, // 6 - 9 Incomplete service list (File Transfer service) #endif @@ -83,13 +83,23 @@ uint8_t circuitpython_scan_response_data[] = { #endif }; -bool boot_in_discovery_mode = false; -bool advertising = false; + +#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE +STATIC bool boot_in_discovery_mode = false; +STATIC bool advertising = false; +STATIC bool ble_started = false; + +#define WORKFLOW_UNSET 0 +#define WORKFLOW_ENABLED 1 +#define WORKFLOW_DISABLED 2 + +STATIC uint8_t workflow_state = WORKFLOW_UNSET; +STATIC bool was_connected = false; STATIC void supervisor_bluetooth_start_advertising(void) { - #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE - return; - #else + if (workflow_state != WORKFLOW_ENABLED) { + return; + } bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj); if (is_connected) { return; @@ -111,7 +121,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) { // Advertise with less power when doing so publicly to reduce who can hear us. This will make it // harder for someone with bad intentions to pair from a distance. if (!bonded) { - tx_power = -40; + tx_power = -20; adv = public_advertising_data; adv_len = sizeof(public_advertising_data); scan_response = circuitpython_scan_response_data; @@ -130,16 +140,15 @@ STATIC void supervisor_bluetooth_start_advertising(void) { NULL); // This may fail if we are already advertising. advertising = status == NRF_SUCCESS; - #endif } +#endif // CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #define BLE_DISCOVERY_DATA_GUARD 0xbb0000bb #define BLE_DISCOVERY_DATA_GUARD_MASK 0xff0000ff void supervisor_bluetooth_init(void) { - #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE - return; - #endif + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE uint32_t reset_state = port_get_saved_word(); uint32_t ble_mode = 0; if ((reset_state & BLE_DISCOVERY_DATA_GUARD_MASK) == BLE_DISCOVERY_DATA_GUARD) { @@ -209,10 +218,14 @@ void supervisor_bluetooth_init(void) { status_led_deinit(); #endif port_set_saved_word(reset_state); + #endif } -STATIC bool was_connected; void supervisor_bluetooth_background(void) { + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + if (!ble_started) { + return; + } bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj); if (was_connected && !is_connected) { #if CIRCUITPY_BLE_FILE_SERVICE @@ -228,12 +241,15 @@ void supervisor_bluetooth_background(void) { #if CIRCUITPY_BLE_FILE_SERVICE supervisor_bluetooth_file_transfer_background(); #endif + #endif } void supervisor_start_bluetooth(void) { - #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE - return; - #endif + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + + if (workflow_state != WORKFLOW_ENABLED) { + return; + } common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true); @@ -245,16 +261,41 @@ void supervisor_start_bluetooth(void) { supervisor_start_bluetooth_serial(); #endif - // Kick off advertisments + // Mark as started so that the background call does something. + ble_started = true; + + // Kick off advertisements supervisor_bluetooth_background(); + + #endif } void supervisor_stop_bluetooth(void) { - #if !CIRCUITPY_BLE_FILE_SERVICE && !CIRCUITPY_SERIAL_BLE - return; - #endif + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + + if (!ble_started && workflow_state != WORKFLOW_ENABLED) { + return; + } #if CIRCUITPY_SERIAL_BLE supervisor_stop_bluetooth_serial(); #endif + + #endif +} + +void supervisor_bluetooth_enable_workflow(void) { + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + if (workflow_state == WORKFLOW_DISABLED) { + return; + } + + workflow_state = WORKFLOW_ENABLED; + #endif +} + +void supervisor_bluetooth_disable_workflow(void) { + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + workflow_state = WORKFLOW_DISABLED; + #endif } diff --git a/supervisor/shared/bluetooth/bluetooth.h b/supervisor/shared/bluetooth/bluetooth.h index 577c0c76a1..9de82719a5 100644 --- a/supervisor/shared/bluetooth/bluetooth.h +++ b/supervisor/shared/bluetooth/bluetooth.h @@ -34,4 +34,8 @@ void supervisor_bluetooth_init(void); void supervisor_start_bluetooth(void); void supervisor_stop_bluetooth(void); +// Enable only works if it hasn't been set yet. +void supervisor_bluetooth_enable_workflow(void); +void supervisor_bluetooth_disable_workflow(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H diff --git a/supervisor/shared/bluetooth/serial.c b/supervisor/shared/bluetooth/serial.c index d852a86d74..059f322649 100644 --- a/supervisor/shared/bluetooth/serial.c +++ b/supervisor/shared/bluetooth/serial.c @@ -166,7 +166,7 @@ void ble_serial_write(const char *text, size_t len) { } size_t sent = 0; while (sent < len) { - uint16_t packet_size = MIN(len, (size_t)common_hal_bleio_packet_buffer_get_outgoing_packet_length(&_tx_packet_buffer)); + uint16_t packet_size = MIN(len - sent, (size_t)common_hal_bleio_packet_buffer_get_outgoing_packet_length(&_tx_packet_buffer)); mp_int_t written = common_hal_bleio_packet_buffer_write(&_tx_packet_buffer, (const uint8_t *)text + sent, packet_size, NULL, 0); // Error, so we drop characters to transmit. if (written < 0) { diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 6ee6c7386a..9cd4f18960 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -123,6 +123,7 @@ void supervisor_stop_terminal(void) { free_memory(tilegrid_tiles); tilegrid_tiles = NULL; supervisor_terminal_text_grid.tiles = NULL; + supervisor_terminal.tilegrid = NULL; } #endif } diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index 6c89026223..056833a8d3 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -101,6 +101,11 @@ uint16_t status_rgb_color[3] = { digitalio_digitalinout_obj_t single_color_led; uint8_t rgb_status_brightness = 0xff; + +#ifndef MICROPY_HW_LED_STATUS_INVERTED +#define MICROPY_HW_LED_STATUS_INVERTED (0) +#endif + #endif #if CIRCUITPY_DIGITALIO && (defined(MICROPY_HW_LED_RX) || defined(MICROPY_HW_LED_TX)) @@ -189,7 +194,8 @@ void status_led_init() { #elif defined(MICROPY_HW_LED_STATUS) common_hal_digitalio_digitalinout_construct(&single_color_led, MICROPY_HW_LED_STATUS); - common_hal_digitalio_digitalinout_switch_to_output(&single_color_led, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output( + &single_color_led, MICROPY_HW_LED_STATUS_INVERTED == 0, DRIVE_MODE_PUSH_PULL); #endif #if CIRCUITPY_DIGITALIO && CIRCUITPY_STATUS_LED @@ -282,7 +288,8 @@ void new_status_color(uint32_t rgb) { common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_g, status_rgb_color[1]); common_hal_pwmio_pwmout_set_duty_cycle(&rgb_status_b, status_rgb_color[2]); #elif CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS) - common_hal_digitalio_digitalinout_set_value(&single_color_led, rgb_adjusted > 0); + common_hal_digitalio_digitalinout_set_value( + &single_color_led, (rgb_adjusted > 0) ^ MICROPY_HW_LED_STATUS_INVERTED); #endif } diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index 7afbd43e21..a14fa5c728 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -35,12 +35,25 @@ #endif #include "py/misc.h" +#include "py/mpprint.h" #include "supervisor/serial.h" void serial_write_compressed(const compressed_string_t *compressed) { - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - serial_write(decompressed); + mp_printf(MP_PYTHON_PRINTER, "%S", compressed); +} + +STATIC void get_word(int n, const mchar_t **pos, const mchar_t **end) { + int len = minlen; + int i = 0; + *pos = words; + while (wlencount[i] <= n) { + n -= wlencount[i]; + *pos += len * wlencount[i]; + i++; + len++; + } + *pos += len * n; + *end = *pos + len; } STATIC int put_utf8(char *buf, int u) { @@ -49,16 +62,14 @@ STATIC int put_utf8(char *buf, int u) { return 1; } else if (word_start <= u && u <= word_end) { uint n = (u - word_start); - size_t pos = 0; - if (n > 0) { - pos = wends[n - 1] + (n * 2); - } + const mchar_t *pos, *end; + get_word(n, &pos, &end); int ret = 0; // note that at present, entries in the words table are // guaranteed not to represent words themselves, so this adds // at most 1 level of recursive call - for (; pos < wends[n] + (n + 1) * 2; pos++) { - int len = put_utf8(buf, words[pos]); + for (; pos < end; pos++) { + int len = put_utf8(buf, *pos); buf += len; ret += len; } diff --git a/supervisor/shared/translate.h b/supervisor/shared/translate.h index 3096fc3e80..da58e1eb78 100644 --- a/supervisor/shared/translate.h +++ b/supervisor/shared/translate.h @@ -50,11 +50,14 @@ // are computed with a heuristic based on frequent substrings of 2 to // 9 code points. These are called "words" but are not, grammatically // speaking, words. They're just spans of code points that frequently -// occur together. +// occur together. They are ordered shortest to longest. // // - dictionary entries are non-overlapping, and the _ending_ index of each -// entry is stored in an array. Since the index given is the ending -// index, the array is called "wends". +// entry is stored in an array. A count of words of each length, from +// minlen to maxlen, is given in the array called wlencount. From +// this small array, the start and end of the N'th word can be +// calculated by an efficient, small loop. (A bit of time is traded +// to reduce the size of this table indicating lengths) // // The "data" / "tail" construct is so that the struct's last member is a // "flexible array". However, the _only_ member is not permitted to be @@ -66,7 +69,7 @@ // flexible array}, but is also future-proofed against strings with // UTF-8 length above 256, with a savings of about 1.375 bytes per // string. -typedef struct { +typedef struct compressed_string { uint8_t data; const uint8_t tail[]; } compressed_string_t; diff --git a/tests/extmod/data/qr.pgm b/tests/extmod/data/qr.pgm new file mode 100644 index 0000000000..c8e5745367 --- /dev/null +++ b/tests/extmod/data/qr.pgm @@ -0,0 +1,5 @@ +P5 +# Created by GIMP version 2.10.22 PNM plug-in +320 240 +255 + \ No newline at end of file diff --git a/tests/extmod/qrio.py b/tests/extmod/qrio.py new file mode 100644 index 0000000000..5e9ed4c12a --- /dev/null +++ b/tests/extmod/qrio.py @@ -0,0 +1,13 @@ +try: + import qrio +except: + print("SKIP") + raise SystemExit + +loc = __file__.rsplit("/", 1)[0] +with open(f"{loc}/data/qr.pgm") as f: + content = f.read()[-320 * 240 :] + +decoder = qrio.QRDecoder(320, 240) +for r in decoder.decode(content): + print(r) diff --git a/tests/extmod/qrio.py.exp b/tests/extmod/qrio.py.exp new file mode 100644 index 0000000000..12d1e24833 --- /dev/null +++ b/tests/extmod/qrio.py.exp @@ -0,0 +1 @@ +QRInfo(payload=b'https://adafru.it', data_type='iso_8859-2') diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 7d87c4f92a..57f4b139f9 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -32,11 +32,11 @@ mport builtins micropython _thread array btree cexample cmath collections cppexample ffi framebuf gc -hashlib math sys termios -ubinascii uctypes uerrno uheapq -uio ujson ulab uos -urandom ure uselect ustruct -utime utimeq uzlib +hashlib math qrio sys +termios ubinascii uctypes uerrno +uheapq uio ujson ulab +uos urandom ure uselect +ustruct utime utimeq uzlib ime utime utimeq diff --git a/tools/adabot b/tools/adabot index 393c275671..f879b24c5f 160000 --- a/tools/adabot +++ b/tools/adabot @@ -1 +1 @@ -Subproject commit 393c2756714b5cccf028a82c23b873d36b2d9e8b +Subproject commit f879b24c5fcf759be3ecbd2ef6c5302b2acc8d28 diff --git a/tools/codeformat.py b/tools/codeformat.py index 32d4eedbf0..863c27fdf5 100644 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -119,6 +119,15 @@ C_EXTS = ( ) PY_EXTS = (".py",) + +def check_uncrustify_version(): + version = subprocess.check_output( + ["uncrustify", "--version"], encoding="utf-8", errors="replace" + ) + if version < "Uncrustify-0.71": + raise SystemExit(f"codeformat.py requires Uncrustify 0.71 or newer, got {version}") + + # Transform a filename argument relative to the current directory into one # relative to the TOP directory, which is what we need when checking against # path_rx. @@ -218,6 +227,7 @@ def main(): # Format C files with uncrustify. if format_c: + check_uncrustify_version() command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"] if not args.v: command.append("-q") diff --git a/tools/fonts/ter-u12n.bdf b/tools/fonts/ter-u12n.bdf index 390d0a1e87..4fba3cc718 100644 --- a/tools/fonts/ter-u12n.bdf +++ b/tools/fonts/ter-u12n.bdf @@ -24,7 +24,7 @@ FONT_ASCENT 10 FONT_DESCENT 2 DEFAULT_CHAR 65533 ENDPROPERTIES -CHARS 1326 +CHARS 1327 STARTCHAR char0 ENCODING 0 SWIDTH 500 0 @@ -6447,7 +6447,6 @@ BITMAP 00 00 ENDCHAR -ENDCHAR STARTCHAR uni01DC ENCODING 476 SWIDTH 1000 0 diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index 04ebc86579..b51c8a40e0 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -228,7 +228,7 @@ terminalio_terminal_obj_t supervisor_terminal = { .font = &supervisor_terminal_font, .cursor_x = 0, .cursor_y = 0, - .tilegrid = &supervisor_terminal_text_grid + .tilegrid = NULL }; """ ) diff --git a/tools/safe_mode_finder.py b/tools/safe_mode_finder.py new file mode 100644 index 0000000000..fece853127 --- /dev/null +++ b/tools/safe_mode_finder.py @@ -0,0 +1,181 @@ +# This uses pyocd to control a Cortex M core, set a breakpoint and dump the stack. +# It is expected that you modify it for your particular case. + +from pyocd.core.helpers import ConnectHelper +from pyocd.core.target import Target +from pyocd.debug.elf.symbols import ELFSymbolProvider +from pyocd.flash.file_programmer import FileProgrammer + +import logging + +# logging.basicConfig(level=logging.DEBUG) + +import sys +import time + +board = sys.argv[1] + +# Connect to the target. +with ConnectHelper.session_with_chosen_probe(target_override="nrf52840") as session: + target = session.target + + # Set ELF file on target. + filename = f"build-{board}/firmware.elf" + target.elf = filename + + e = target.elf._elf + + # Look up address of reset_into_safe_mode(). + provider = ELFSymbolProvider(target.elf) + addr = provider.get_symbol_value("reset_into_safe_mode") + print("reset_into_safe_mode() address: 0x%X" % addr) + + for section in target.elf.sections: + print(section) + print() + + print("loading", filename) + # FileProgrammer(session).program(filename, file_format="elf") + print("load done") + + # Set breakpoint. + target.set_breakpoint(addr) + # target.set_watchpoint(0x20010558, 4, Target.WatchpointType.WRITE) + + # Reset and run. + target.reset_and_halt() + for i in range(1): + target.resume() + + print("resuming") + start = time.monotonic() + # Wait 10s until breakpoint is hit. + while target.get_state() != Target.State.HALTED and time.monotonic() - start < 10: + pass + + # value = target.read_memory(0x20010558) + # print(f"{value:08x}") + + # time.sleep(2) + + target.halt() + + # print("_sidata", hex(provider.get_symbol_value("_sidata"))) + + # flash_start = 0x000affe8 + # ram_start = 0x20010000 + # for i in range(0, 0x55c, 4): + # flash_value = target.read_memory(flash_start + i) + # value = target.read_memory(ram_start + i) + # diff = "" + # if flash_value != value: + # diff = "*" + # print(f"{ram_start + i:08x} {flash_value:08x} {value:08x} {diff}") + + # Print PC. + pc = target.read_core_register("pc") + print("pc: 0x%X" % pc) + print(target.elf.symbol_decoder.get_symbol_for_address(pc)) + sp = target.read_core_register("sp") + print("sp: 0x%X" % sp) + msp = target.read_core_register("msp") + print("msp: 0x%X" % msp) + psp = target.read_core_register("psp") + print("psp: 0x%X" % psp) + + print(e.has_dwarf_info()) + d = e.get_dwarf_info() + # print(dir(d)) + aranges = d.get_aranges() + cu_offset = aranges.cu_offset_at_addr(pc) + if not cu_offset: + cu_offset = 0 + main_cu = d.get_CU_at(cu_offset) + lines = d.line_program_for_CU(main_cu).get_entries() + + lines_by_address = {} + for line in lines: + if not line.state: + # print(line) + continue + lines_by_address[line.state.address] = line.state + call_frames = None + # if d.has_CFI(): + # print("CFI") + # call_frames = d.CFI_entries() + # if d.has_EH_CFI(): + # print("EH CFI") + # call_frames = d.EH_CFI_entries() + all_frames = {} + # for frame in call_frames: + # decoded = frame.get_decoded() + # for entry in decoded.table: + # entry_pc = entry["pc"] + # all_frames[entry_pc] = decoded + # for r in d.range_lists().iter_range_lists(): + # print(r) + if pc in all_frames: + print(all_frames[pc]) + ad = target.elf.address_decoder + function = ad.get_function_for_address(pc) + if function: + print(" ", function) + line = ad.get_line_for_address(pc) + if line: + print(" ", line) + + mm = target.get_memory_map() + + ram = mm.get_region_for_address(sp) + if not ram: + sp_guess = 0x20013BCC + print("stack pointer bad using 0x{%08x}") + ram = mm.get_region_for_address(sp_guess) + stack_address = sp + offset = 0 + while ram and sp + offset <= ram.end: + stack_address = sp + offset + value = target.read_memory(stack_address) + symbol = target.elf.symbol_decoder.get_symbol_for_address(value) + print(f"{stack_address:08x} {offset:04x} {value:08x} {symbol}") + function = ad.get_function_for_address(value) + if function: + print(" ", function) + line = ad.get_line_for_address(value) + if line: + print(" ", line) + # value -= 0x27000 + # if value in all_frames: + # print(all_frames[value]) + # if value in lines_by_address: + # print(lines_by_address[value]) + offset += 4 + + top_symbol = target.elf.symbol_decoder.get_symbol_for_address(target.read_memory(sp)) + if True or (top_symbol and top_symbol.name == "HardFault_Handler"): + lr = target.read_core_register("lr") + print("lr: 0x%08X" % lr) + cfsr = target.read_memory(0xE000ED28) + print("cfsr: 0x%08X" % cfsr) + hfsr = target.read_memory(0xE000ED2C) + print("hfsr: 0x%08X" % hfsr) + if hfsr & 0x4000_0000: + print("hard fault forced") + bfsr = (cfsr >> 8) & 0xFF + if bfsr & 0x80 != 0: + bad_address = target.read_memory(0xE000ED38) + print(f"bus fault with address 0x{bad_address:08x}") + bits = ["IBUSERR", "PRECISERR", "IMPRECISERR", "UNSTKERR", "STKERR", "LSPERR"] + for i, bit in enumerate(bits): + if bfsr & (1 << i): + print(bit) + + for i in range(13): + reg = f"r{i}" + value = target.read_core_register(reg) + print(f"{reg} 0x{value:08x}") + + # print(hex(target.read_memory(provider.get_symbol_value("prescaler")))) + + # Remove breakpoint. + target.remove_breakpoint(addr)