diff --git a/.gitmodules b/.gitmodules index 2ba84b4305..9c8d3b4b68 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,9 +33,6 @@ path = ports/atmel-samd/asf4 url = https://github.com/adafruit/asf4.git branch = circuitpython -[submodule "tools/usb_descriptor"] - path = tools/usb_descriptor - url = https://github.com/adafruit/usb_descriptor.git [submodule "lib/nrfutil"] path = lib/nrfutil url = https://github.com/adafruit/nRF52_nrfutil @@ -103,7 +100,7 @@ url = https://github.com/adafruit/Adafruit_MP3 [submodule "ports/mimxrt10xx/sdk"] path = ports/mimxrt10xx/sdk - url = https://github.com/adafruit/MIMXRT10xx_SDK + url = https://github.com/nxp-mcuxpresso/mcux-sdk.git [submodule "frozen/Adafruit_CircuitPython_Register"] path = frozen/Adafruit_CircuitPython_Register url = https://github.com/adafruit/Adafruit_CircuitPython_Register.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8cc372d0f..ab0279f7d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: rev: v2.2.4 hooks: - id: codespell - #args: [-w] + args: [-w] exclude: | (?x)^( locale/| diff --git a/Makefile b/Makefile index 91d842231f..50c86fc128 100644 --- a/Makefile +++ b/Makefile @@ -324,10 +324,9 @@ clean-stm: $(MAKE) -C ports/stm BOARD=feather_stm32f405_express clean -# This update will fail because the commits we need aren't the latest on the -# branch. We can ignore that though because we fix it with the second command. -# (Only works for git servers that allow sha fetches.) +# Do blobless partial clones of submodules to save time and space. +# A blobless partial clone lazily fetches data as needed, but has all the metadata available (tags, etc.) +# so it does not have the idiosyncrasies of a shallow clone. .PHONY: fetch-submodules fetch-submodules: - git submodule update --init -N --depth 1 || true - git submodule foreach 'git fetch --tags --depth 1 origin $$sha1 && git checkout -q $$sha1' + git submodule update --init --filter=blob:none diff --git a/docs/design_guide.rst b/docs/design_guide.rst index 784284892c..40ce285177 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -742,14 +742,7 @@ You could other examples if needed featuring different functionalities of the library. If you add additional examples, be sure to include them in the ``examples.rst``. Naming of the examples files should use the name of the library followed by a description, using underscore to separate them. -When using print statements you should use the ``" ".format()`` format, as there are particular boards -that are not capable to use f-strings. -.. code-block:: python - - text_to_display = "World!" - - print("Hello {}".format(text_to_display)) Sensor properties and units -------------------------------------------------------------------------------- diff --git a/lib/tinyusb b/lib/tinyusb index ea8ecea59a..ec9c666107 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit ea8ecea59aa60a1028cce16b0f15bb33918b11af +Subproject commit ec9c666107c0be0f8dc7c2a15e3bdea8c44a50b4 diff --git a/locale/ID.po b/locale/ID.po index f6960665b4..a136f6e498 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -30,14 +30,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1264,6 +1256,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index f3e6ffc341..55ab977e97 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -28,14 +28,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1253,6 +1245,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" @@ -2741,7 +2737,7 @@ msgstr "" msgid "can't set attribute" msgstr "" -#: py/runtime.c +#: py/runtime.c shared-bindings/supervisor/Runtime.c msgid "can't set attribute '%q'" msgstr "" @@ -4115,10 +4111,6 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/struct/__init__.c -msgid "too many arguments provided with the given format" -msgstr "" - #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 0ffdbdcc67..1d666730ec 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -32,14 +32,6 @@ msgstr "" "\n" "Kód byl zastaven kvůli automatickému načtení. K načtení dojde brzy.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1264,6 +1256,10 @@ msgstr "Chybný BLE parametr" msgid "Invalid BSSID" msgstr "Chybné BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Chybná MAC adresa" diff --git a/locale/de_DE.po b/locale/de_DE.po index 9f2c83e8cc..f6bc0b789e 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -31,18 +31,6 @@ msgstr "" "\n" "Code wurde durch automatisches Neuladen gestoppt. Wird bald neu geladen.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"Ungültige CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1287,6 +1275,10 @@ msgstr "Ungültiges BLE Parameter" msgid "Invalid BSSID" msgstr "Ungültige BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Ungültige MAC-Adresse" @@ -4473,6 +4465,17 @@ msgstr "zi muss eine Gleitkommazahl sein" msgid "zi must be of shape (n_section, 2)" msgstr "zi muss die Form (n_section, 2) haben" +#~ msgid "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "Ungültige CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Gib mindestens einen UART-Pin an" diff --git a/locale/el.po b/locale/el.po index 81118aa8fd..f2382feb94 100644 --- a/locale/el.po +++ b/locale/el.po @@ -35,14 +35,6 @@ msgstr "" "Ο κώδικας σταμάτησε λόγω της αυτόματης επαναφόρτωσης. Η επαναφόρτωση θα " "γίνει σύντομα.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1273,6 +1265,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index 9ced3137b9..45131d1dcb 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -34,14 +34,6 @@ msgstr "" "\n" "Code stopped by auto-reload. Reloading soon.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1265,6 +1257,10 @@ msgstr "Invalid BLE parameter" msgid "Invalid BSSID" msgstr "Invalid BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/es.po b/locale/es.po index ee2af9d603..cf81206c3d 100644 --- a/locale/es.po +++ b/locale/es.po @@ -34,18 +34,6 @@ msgstr "" "\n" "Código detenido por la auto-recarga. Recargando pronto.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"CIRCUITPY_PYSTACK_SIZE inválido\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1302,6 +1290,10 @@ msgstr "Parámetro BLE invalido" msgid "Invalid BSSID" msgstr "BSSID inválido" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Dirección MAC inválida" @@ -4481,6 +4473,17 @@ 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 "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE inválido\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Suministre al menos un pin UART" diff --git a/locale/fil.po b/locale/fil.po index f943746a34..591620e6c4 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -29,14 +29,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1264,6 +1256,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 424e16a1b5..4ebcc918bf 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -34,18 +34,6 @@ msgstr "" "Le code a été arrêté par l'actualisation automatique. Rechargement " "prochain.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"CIRCUITPY_PYSTACK_SIZE invalide\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1308,6 +1296,10 @@ msgstr "Paramètre BLE invalide" msgid "Invalid BSSID" msgstr "BSSID invalide" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Adresse MAC invalide" @@ -4500,6 +4492,17 @@ 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 "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE invalide\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Fournissez au moins une broche UART" diff --git a/locale/hi.po b/locale/hi.po index 94a42e19f8..2b9825e4b8 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -28,14 +28,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1252,6 +1244,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 5fb7e50d6b..84bc790df4 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -31,14 +31,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1266,6 +1258,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/ja.po b/locale/ja.po index 7e63cb55c3..081dd57e9f 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -34,14 +34,6 @@ msgstr "" "\n" "オートリロードでコード実行は中止された。まもなくリロードする。\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1265,6 +1257,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "不正なBSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/ko.po b/locale/ko.po index 129c9b4bcd..7668d8c8a3 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -29,14 +29,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1255,6 +1247,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 87fdb61c60..61c96a877d 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -28,14 +28,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1260,6 +1252,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "Ongeldig BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/pl.po b/locale/pl.po index 1348c0f321..642e5f99de 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -30,14 +30,6 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1260,6 +1252,10 @@ msgstr "" msgid "Invalid BSSID" msgstr "" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index fdf2eaaf31..bef3ea8849 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -32,18 +32,6 @@ msgstr "" "\n" "O código parou pela recarga automática. Recarregando em breve.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"CIRCUITPY_PYSTACK_SIZE inválido\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1298,6 +1286,10 @@ msgstr "Parâmetro BLE inválido" msgid "Invalid BSSID" msgstr "BSSID Inválido" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Endereço MAC inválido" @@ -4481,6 +4473,17 @@ 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 "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "CIRCUITPY_PYSTACK_SIZE inválido\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Forneça pelo menos um pino UART" diff --git a/locale/ru.po b/locale/ru.po index 0fe6cfac97..2ad4b094a2 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -34,14 +34,6 @@ msgstr "" "\n" "Программа остановлена автоматической перезагрузкой. Скоро перезагрузка.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1297,6 +1289,10 @@ msgstr "Недопустимый параметр BLE" msgid "Invalid BSSID" msgstr "Неверный BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Неверный MAC-адрес" diff --git a/locale/sv.po b/locale/sv.po index 84ce4b6ecb..3c2c9f6520 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -32,18 +32,6 @@ msgstr "" "\n" "Koden stoppades av automatisk laddning. Omladdning sker strax.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"Ogiltig CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1283,6 +1271,10 @@ msgstr "Ogiltig BLE-parameter" msgid "Invalid BSSID" msgstr "Ogiltig BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Ogiltig MAC-adress" @@ -4443,6 +4435,17 @@ 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 "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "Ogiltig CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Ange minst en UART-pinne" diff --git a/locale/tr.po b/locale/tr.po index 67a73375ea..bd9d746940 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -34,14 +34,6 @@ msgstr "" "Program otomatik yeniden yükleme tarafından durduruldu. Birazdan tekrar " "yüklenecek.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1270,6 +1262,10 @@ msgstr "Geçersiz BLE parametresi" msgid "Invalid BSSID" msgstr "Geçersiz BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "Geçersiz MAC adresi" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 485c30353d..72df0f5aed 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -34,18 +34,6 @@ msgstr "" "dài mǎ yīn zì dòng chóng xīn jiā zǎi ér tíng zhǐ. jí jiāng chóng xīn jiā " "zǎi.\n" -#: main.c -msgid "" -"\n" -"Invalid CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\r" -msgstr "" -"\n" -"wú xiào CIRCUITPY_PYSTACK_SIZE\n" -"\n" -"\n" - #: supervisor/shared/safe_mode.c msgid "" "\n" @@ -1290,6 +1278,10 @@ msgstr "wú xiào BLE cān shù" msgid "Invalid BSSID" msgstr "Wúxiào de BSSID" +#: main.c +msgid "Invalid CIRCUITPY_PYSTACK_SIZE\n" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" msgstr "wú xiào de MAC dì zhǐ" @@ -4449,6 +4441,17 @@ 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 "" +#~ "\n" +#~ "Invalid CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\r" +#~ msgstr "" +#~ "\n" +#~ "wú xiào CIRCUITPY_PYSTACK_SIZE\n" +#~ "\n" +#~ "\n" + #~ msgid "Supply at least one UART pin" #~ msgstr "Dìngyì zhìshǎo yīgè UART yǐn jiǎo" diff --git a/main.c b/main.c index 002c97c167..7b805b57b0 100644 --- a/main.c +++ b/main.c @@ -134,26 +134,18 @@ static void reset_devices(void) { #if MICROPY_ENABLE_PYSTACK STATIC supervisor_allocation *allocate_pystack(safe_mode_t safe_mode) { - mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE; #if CIRCUITPY_OS_GETENV && CIRCUITPY_SETTABLE_PYSTACK - // Fetch value if exists from settings.toml - // Leaves size to build default on any failure - if (safe_mode == SAFE_MODE_NONE || safe_mode == SAFE_MODE_USER) { + if (safe_mode == SAFE_MODE_NONE) { + mp_int_t pystack_size = CIRCUITPY_PYSTACK_SIZE; (void)common_hal_os_getenv_int("CIRCUITPY_PYSTACK_SIZE", &pystack_size); - // Check if value is valid - pystack_size = pystack_size - pystack_size % sizeof(size_t); // Round down to multiple of 4. - if ((pystack_size < 384) || (pystack_size > 900000)) { - serial_write_compressed(translate("\nInvalid CIRCUITPY_PYSTACK_SIZE\n\n\r")); - pystack_size = CIRCUITPY_PYSTACK_SIZE; // Reset + supervisor_allocation *pystack = allocate_memory(pystack_size >= 384 ? pystack_size : 0, false, false); + if (pystack) { + return pystack; } + serial_write_compressed(translate("Invalid CIRCUITPY_PYSTACK_SIZE\n")); } #endif - supervisor_allocation *pystack = allocate_memory(pystack_size, false, false); - if (pystack == NULL) { - serial_write_compressed(translate("\nInvalid CIRCUITPY_PYSTACK_SIZE\n\n\r")); - pystack = allocate_memory(CIRCUITPY_PYSTACK_SIZE, false, false); - } - return pystack; + return allocate_memory(CIRCUITPY_PYSTACK_SIZE, false, false); } #endif diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 0ac326d3cc..5a4e5111da 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -366,7 +366,7 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE) $(STEPECHO) "LINK $@" $(Q)echo $(OBJ) > $(BUILD)/firmware.objs - $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(GENERATED_LD_FILE) $(BUILD) $(BUILD)/firmware.bin: $(BUILD)/firmware.elf diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c new file mode 100644 index 0000000000..630de0b63f --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c @@ -0,0 +1,114 @@ +/* + * 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 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, DELAY | 1, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x36, 0x01, 0x08, // _MADCTL + 0x21, DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0xC0, // _MADCTL + 0x29, DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +static void display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO18, // CLK + &pin_GPIO19, // MOSI + NULL, // MISO not connected + false); // Not half-duplex + + 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_GPIO16, // DC + &pin_GPIO5, // CS + &pin_GPIO23, // RST + 24000000, // baudrate (default from the driver) + // 40000000, + 0, // polarity + 0 // phase + ); + + 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) + 135, // height (after rotation) + 53, // column start + 40, // row start + 270, // 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 + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO4, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h new file mode 100644 index 0000000000..39febafb6a --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.h @@ -0,0 +1,34 @@ +/* + * 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 "LILYGO TTGO T-DISPLAY v1.1" +#define MICROPY_HW_MCU_NAME "ESP32" + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk new file mode 100644 index 0000000000..dd177ec1c9 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0xC3C30000 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/pins.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/pins.c new file mode 100644 index 0000000000..5a72b0f416 --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/pins.c @@ -0,0 +1,41 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { 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_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + // 1.14 inch LCD ST7789 + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // Battery Sense + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO34) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig new file mode 100644 index 0000000000..55052e98ca --- /dev/null +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig @@ -0,0 +1,5 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-TDISPLAY" +# end of LWIP diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c new file mode 100644 index 0000000000..6a60ada6b0 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c @@ -0,0 +1,161 @@ +/* + * 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 + +// display init sequence for ST7789 (works in python) +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 0x96, + // sleep out + 0x11, 0 | DELAY, 0xFF, + 0x3A, 1 | DELAY, 0x55, 10, + 0x36, 1, 0x08, + 0x21, 0 | DELAY, 10, + 0x13, 0 | DELAY, 10, + 0x36, 1, 0xC0, + // display on + 0x29, 0 | DELAY, 255, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO18, // CLK + &pin_GPIO19, // MOSI + NULL, // MISO not connected + false // Not half-duplex + ); + + 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_GPIO27, // DC + &pin_GPIO5, // CS + NULL, // RST + 24000000, // baudrate + 0, // polarity + 0 // phase + ); + + 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 + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO15, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 5000 // backlight pwm frequency + ); +} + +/* +#define APX202_ADDRESS (0x35) +#define AXP202_LDO2 (2) +#define AXP202_ON (1) +#define AXP202_OFF (0) +#define AXP202_DCDC3 (1) +#define AXP202_IC_TYPE (0x03) +#define AXP202_LDO234_DC23_CTL (0x12) +#define AXP_PASS (1) +#define AXP_FAIL (-1) +#define AXP202_CHIP_ID (0x41) +#define AXP192_CHIP_ID (0x03) +#define FORCED_OPEN_DCDC3(x) (x |= (AXP202_ON << AXP202_DCDC3)) + +static void backlight_init(void) { + // Turn LDO2 on for display + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + uint8_t data = 0; + uint8_t outputReg = 0; + uint8_t read = 0; + // lock + // _readByte(AXP202_LDO234_DC23_CTL, 1, &outputReg) + // time.sleep(0.001) + // _readByte(AXP202_LDO234_DC23_CTL, 1, &data) + // time.sleep(0.001) + // data |= 1 << AXP202_LDO2 + // FORCED_OPEN_DCDC3(data) + // _writeByte(AXP202_LDO234_DC23_CTL, 1, &data) + // time.sleep(0.001) + // unlock +} +*/ + +void board_init(void) { + // Display + display_init(); + // backlight_init(); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == MOTOR_PIN) { + // no motor + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, false); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h new file mode 100644 index 0000000000..bf65b394f7 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Lilygo T-watch 2020 V3" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MOTOR_PIN (4) +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}, \ + {.scl = &pin_GPIO32, .sda = &pin_GPIO23}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = NULL}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.mk b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.mk new file mode 100644 index 0000000000..9d6c8dc25b --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0xC3C30000 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c b/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c new file mode 100644 index 0000000000..8dd20b1a69 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(touch_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // buzz buzz + { MP_ROM_QSTR(MP_QSTR_VIBRATE), MP_ROM_PTR(&pin_GPIO4) }, + + // I2S out + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_GPIO33) }, + + // PDM in + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_GPIO2) }, + + // IR send + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + // main I2C port, for the AXP202, and 2 others + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // interrupt pins for sensors + { MP_ROM_QSTR(MP_QSTR_BMA423_INT), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_PCF8563_INT), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_AXP202_INT), MP_ROM_PTR(&pin_GPIO35) }, + + // I2C port for the FT6336 touch sensor + { MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_TOUCH_I2C), MP_ROM_PTR(&board_touch_i2c_obj) }, + + // LCD display + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BRIGHTNESS), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig new file mode 100644 index 0000000000..89647ab5a1 --- /dev/null +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig @@ -0,0 +1,31 @@ +# SPI RAM config +# +CONFIG_ESP32_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_TYPE_ESPPSRAM64=y +CONFIG_SPIRAM_SIZE=8388608 +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_BOOT_INIT=y +# CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_CACHE_WORKAROUND=y + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +# +# ESP System Settings +# +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +CONFIG_ESP_CONSOLE_UART_CUSTOM=y +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_TX_GPIO=1 +CONFIG_ESP_CONSOLE_UART_RX_GPIO=3 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +# end of ESP System Settings diff --git a/ports/espressif/boards/lolin_s2_pico/board.c b/ports/espressif/boards/lolin_s2_pico/board.c index b3c8cb4191..e2c24bb22a 100644 --- a/ports/espressif/boards/lolin_s2_pico/board.c +++ b/ports/espressif/boards/lolin_s2_pico/board.c @@ -27,8 +27,76 @@ #include "supervisor/board.h" #include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/I2CDisplay.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/I2C.h" +#include "supervisor/shared/board.h" +#include "shared-bindings/board/__init__.h" + +uint8_t display_init_sequence[] = { // SSD1306 + 0xAE, 0, // DISPLAY_OFF + 0x20, 1, 0x00, // Set memory addressing to horizontal mode. + 0x81, 1, 0xcf, // set contrast control + 0xA1, 0, // Column 127 is segment 0 + 0xA6, 0, // Normal display + 0xc8, 0, // Normal display + 0xA8, 1, 0x1f, // Mux ratio is height-1 + 0xd5, 1, 0x80, // Set divide ratio + 0xd9, 1, 0xf1, // Set pre-charge period + 0xda, 1, 0x02, // Set com configuration to 2 if height is 32 and width not 64 + 0xdb, 1, 0x40, // Set vcom configuration + 0x8d, 1, 0x14, // Enable charge pump + 0xAF, 0, // DISPLAY_ON +}; + +static void display_init(void) { + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + + displayio_i2cdisplay_obj_t *bus = &displays[0].i2cdisplay_bus; + bus->base.type = &displayio_i2cdisplay_type; + common_hal_displayio_i2cdisplay_construct(bus, + i2c, + 0x3c, + &pin_GPIO18 // reset + ); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 128, // Width + 32, // Height + 0, // column start + 0, // row start + 0, // rotation + 1, // Color depth + true, // grayscale + false, // pixels in byte share row. Only used with depth < 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 + 0x21, // Set column command + 0x22, // Set row command + 44, // Write ram command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // no backlight pin + 0x81, // brightness command + 1.0f, // brightness + true, // single_byte_bounds + true, // data as commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 0); // backlight pwm frequency +} void board_init(void) { + // init display + display_init(); // Debug UART #ifdef DEBUG common_hal_never_reset_pin(&pin_GPIO43); diff --git a/ports/espressif/boards/lolin_s2_pico/pins.c b/ports/espressif/boards/lolin_s2_pico/pins.c index 5c3f1f4db5..1afd508f03 100644 --- a/ports/espressif/boards/lolin_s2_pico/pins.c +++ b/ports/espressif/boards/lolin_s2_pico/pins.c @@ -1,4 +1,5 @@ #include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS @@ -52,5 +53,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, // Not labelled on booard, on schematic { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) },// Not labelled on booard, on schematic { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index 8b6cff30ef..19e83e717f 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -253,9 +253,7 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ uint64_t start_ticks = supervisor_ticks_ms64(); // Allow timeouts and interrupts - while (newsoc == -1 && - !timed_out && - !mp_hal_is_interrupted()) { + while (newsoc == -1 && !timed_out) { if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; } @@ -267,9 +265,6 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ } } - // New client socket will not be non-blocking by default, so make it non-blocking. - lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); - if (!timed_out) { // harmless on failure but avoiding memcpy is faster memcpy((void *)ip, (void *)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr)); @@ -280,6 +275,10 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_ if (newsoc < 0) { return -MP_EBADF; } + + // We got a socket. New client socket will not be non-blocking by default, so make it non-blocking. + lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK); + if (!register_open_socket(newsoc)) { lwip_close(newsoc); return -MP_EBADF; diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index b38f120ee2..d8d12b74da 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -30,8 +30,7 @@ CROSS_COMPILE = arm-none-eabi- INC += \ -I. \ -I../.. \ - -I../lib/mp-readline \ - -I../shared/timeutils \ + -I../../lib/cmsis/inc \ -I../../lib/tinyusb/src \ -I../../supervisor/shared/usb \ -I$(BUILD) \ @@ -42,14 +41,19 @@ INC += \ -Isdk/CMSIS/Include \ -Isdk/devices/$(CHIP_FAMILY) \ -Isdk/devices/$(CHIP_FAMILY)/drivers \ - -Isdk/devices/$(CHIP_FAMILY)/xip \ + -Isdk/drivers/common # NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. CFLAGS += -ftree-vrp -DNDEBUG # TinyUSB defines -CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_CDC_RX_BUFSIZE=512 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=512 -DCFG_TUD_MSC_BUFSIZE=1024 +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX -DCFG_TUD_CDC_RX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=512 +ifeq ($(CHIP_FAMILY), MIMXRT1011) +CFLAGS += -DCFG_TUD_MIDI_RX_BUFSIZE=64 -DCFG_TUD_MIDI_TX_BUFSIZE=64 -DCFG_TUD_MSC_BUFSIZE=512 +else +CFLAGS += -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_MSC_BUFSIZE=1024 +endif #Debugging/Optimization # Never set -fno-inline because we use inline to move small functions into routines that must be @@ -76,11 +80,15 @@ CFLAGS += \ -g3 -Wno-unused-parameter \ -ffunction-sections -fdata-sections -fstack-usage -OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions +OPTIMIZATION_FLAGS ?= -O2 # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) +ifeq ($(CIRCUITPY_SWO_TRACE), 1) + CFLAGS += -finstrument-functions -finstrument-functions-exclude-file-list=tinyusb -finstrument-functions-exclude-function-list='USB_OTG1_IRQHandler,usb_irq_handler,nlr_push,CLOCK_EnableClock,CLOCK_SetDiv,CLOCK_SetMux,__DMB,__ISB,__DSB,SCB_EnableICache,SCB_EnableDCache,ARM_MPU_Disable,ARM_MPU_Enable,SCB_DisableDCache,SCB_DisableICache,__enable_irq,__disable_irq,__set_MSP,port_get_raw_ticks,supervisor_ticks_ms64' +endif + LD_FILES = $(wildcard boards/$(BOARD)/*.ld) $(addprefix linking/, flash/$(FLASH).ld chip_family/$(CHIP_FAMILY).ld common.ld) LD_SCRIPT_FLAG := -Wl,-T, @@ -97,25 +105,26 @@ LDFLAGS += -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -mthumb -mapcs BOOTLOADER_SIZE := 0x6000C000 SRC_SDK := \ - drivers/fsl_adc.c \ - drivers/fsl_cache.c \ - drivers/fsl_clock.c \ - drivers/fsl_common.c \ - drivers/fsl_flexspi.c \ - drivers/fsl_gpio.c \ - drivers/fsl_lpi2c.c \ - drivers/fsl_lpspi.c \ - drivers/fsl_lpuart.c \ - drivers/fsl_ocotp.c \ - drivers/fsl_pwm.c \ - drivers/fsl_snvs_hp.c \ - drivers/fsl_snvs_lp.c \ - drivers/fsl_tempmon.c \ - drivers/fsl_trng.c \ - system_$(CHIP_FAMILY).c \ + devices/$(CHIP_FAMILY)/drivers/fsl_clock.c \ + devices/$(CHIP_FAMILY)/system_$(CHIP_FAMILY).c \ + devices/$(CHIP_FAMILY)/xip/fsl_flexspi_nor_boot.c \ + drivers/adc_12b1msps_sar/fsl_adc.c \ + drivers/cache/armv7-m7/fsl_cache.c \ + drivers/common/fsl_common_arm.c \ + drivers/common/fsl_common.c \ + drivers/flexspi/fsl_flexspi.c \ + drivers/igpio/fsl_gpio.c \ + drivers/lpi2c/fsl_lpi2c.c \ + drivers/lpspi/fsl_lpspi.c \ + drivers/lpuart/fsl_lpuart.c \ + drivers/ocotp/fsl_ocotp.c \ + drivers/pwm/fsl_pwm.c \ + drivers/snvs_hp/fsl_snvs_hp.c \ + drivers/snvs_lp/fsl_snvs_lp.c \ + drivers/tempmon/fsl_tempmon.c \ + drivers/trng/fsl_trng.c \ -SRC_SDK := $(addprefix sdk/devices/$(CHIP_FAMILY)/, $(SRC_SDK)) -$(addprefix $(BUILD)/, $(SRC_SDK:.c=.o)): CFLAGS += -Wno-undef -Wno-missing-prototypes -Wno-cast-align +SRC_SDK := $(addprefix sdk/, $(SRC_SDK)) SRC_C += \ background.c \ @@ -171,20 +180,21 @@ all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.hex $(BUILD)/firmware.elf: $(OBJ) $(LD_FILES) $(STEPECHO) "LINK $@" - $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(CC) -o $@ $(LDFLAGS) $(filter-out %.ld, $^) -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group +# -R excludes sections from the output files. $(BUILD)/firmware.bin: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" - $(Q)$(OBJCOPY) -O binary -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@ + $(Q)$(OBJCOPY) -O binary -R .stack -R .dtcm_bss $^ $@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.elf $(STEPECHO) "Create $@" - $(Q)$(OBJCOPY) -O binary -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $^ $@-binpart + $(Q)$(OBJCOPY) -O binary -R .stack -R .dtcm_bss -R .ivt -R .flash_config $^ $@-binpart $(Q)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -f MIMXRT10XX -c -o $@ $@-binpart $(Q)rm $@-binpart $(BUILD)/firmware.hex: $(BUILD)/firmware.elf - $(Q)$(OBJCOPY) -O ihex -j .flash_config -j .ivt -j .text -j .ARM.exidx -j .data -j .itcm -j .dtcm_data $< $@ + $(Q)$(OBJCOPY) -O ihex -R .stack -R .dtcm_bss $< $@ include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt10xx/background.c b/ports/mimxrt10xx/background.c index 5815c222b4..529f791a39 100644 --- a/ports/mimxrt10xx/background.c +++ b/ports/mimxrt10xx/background.c @@ -27,7 +27,11 @@ #include "supervisor/port.h" -void port_background_task(void) { +#include "supervisor/linker.h" + +#include "fsl_common.h" + +void PLACE_IN_ITCM(port_background_task)(void) { } void port_background_tick(void) { @@ -38,5 +42,6 @@ void port_background_tick(void) { void port_start_background_task(void) { } + void port_finish_background_task(void) { } diff --git a/ports/mimxrt10xx/board.h b/ports/mimxrt10xx/board.h deleted file mode 100644 index 1c9596e7d2..0000000000 --- a/ports/mimxrt10xx/board.h +++ /dev/null @@ -1 +0,0 @@ -// Empty but needed for the SDK diff --git a/ports/mimxrt10xx/boards/board.h b/ports/mimxrt10xx/boards/board.h new file mode 100644 index 0000000000..e6736806ed --- /dev/null +++ b/ports/mimxrt10xx/boards/board.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 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 "mpconfigboard.h" + +#define XIP_BOOT_HEADER_ENABLE (1) diff --git a/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c index 5871dda963..4e189590d0 100644 --- a/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_m7_1011/flash_config.c @@ -7,47 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q32JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -61,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, // Bit pattern for setting Quad Enable. - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -78,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -101,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status -2 - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01 /* number of bytes to write */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -128,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -147,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c index 7460615c4c..2c6fa962aa 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1011/flash_config.c @@ -7,47 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -61,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -78,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -101,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -128,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -147,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c index d6cfc07e62..2c6fa962aa 100644 --- a/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c +++ b/ports/mimxrt10xx/boards/feather_mimxrt1062/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_133MHz, + .serialClkFreq = kFLEXSPISerialClk_133MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/flash_config.h b/ports/mimxrt10xx/boards/flash_config.h index 25f1550ae8..b0be0a93c0 100644 --- a/ports/mimxrt10xx/boards/flash_config.h +++ b/ports/mimxrt10xx/boards/flash_config.h @@ -34,7 +34,41 @@ #include "mpconfigboard.h" // For flash size settings #include "fsl_common.h" -#include "fsl_flexspi_nor_config.h" +#ifdef CPU_MIMXRT1011DAE5A +// TODO: Remove this when the 1011 has a romapi header that matches the others. +#include "sdk/boards/evkmimxrt1010/xip/evkmimxrt1010_flexspi_nor_config.h" +typedef enum _flexspi_serial_clk_freq_caps +{ + kFLEXSPISerialClk_NoChange = 0U, + kFLEXSPISerialClk_30MHz = 1U, + kFLEXSPISerialClk_50MHz = 2U, + kFLEXSPISerialClk_60MHz = 3U, + kFLEXSPISerialClk_75MHz = 4U, + kFLEXSPISerialClk_80MHz = 5U, + kFLEXSPISerialClk_100MHz = 6U, + kFLEXSPISerialClk_133MHz = 7U, + kFLEXSPISerialClk_166MHz = 8U, + kFLEXSPISerialClk_200MHz = 9U, +} caps_flexspi_serial_clk_freq_t; + +/*! @brief FLEXSPI Read Sample Clock Source definition */ +typedef enum _flexspi_read_sample_clk_caps +{ + kFLEXSPIReadSampleClk_LoopbackInternally = 0U, + kFLEXSPIReadSampleClk_LoopbackFromDqsPad = 1U, + kFLEXSPIReadSampleClk_LoopbackFromSckPad = 2U, + kFLEXSPIReadSampleClk_ExternalInputFromDqsPad = 3U, +} caps_flexspi_read_sample_clk_t; + +enum +{ + kFLEXSPIDeviceType_SerialNOR = 1U, /*!< Flash device is Serial NOR */ +}; + +#define FSL_ROM_FLEXSPI_LUT_SEQ FLEXSPI_LUT_SEQ +#else +#include "fsl_romapi.h" +#endif #define SEQUENCE(first, second, third, fourth) first, second, third, fourth #define TWO_EMPTY_STEPS 0x00000000 diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c index 9c88f689d8..f15a3f3459 100644 --- a/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1010_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for AT25SF128A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h index 77d458d75b..192c265f88 100644 --- a/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h +++ b/ports/mimxrt10xx/boards/imxrt1010_evk/mpconfigboard.h @@ -16,3 +16,8 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO_09) #define DEFAULT_UART_BUS_TX (&pin_GPIO_10) + +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO_09) +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO_10) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO_11) diff --git a/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c index 6589ad9c48..2ae8ae9b76 100644 --- a/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1020_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for IS25LP064A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x40, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_30MHz, + .serialClkFreq = kFLEXSPISerialClk_30MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - // SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + // SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, // RADDR_SDR, FLEXSPI_4PAD, 24 bits to transmit ), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, // READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c index 40db33444f..c75174d1c4 100644 --- a/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c +++ b/ports/mimxrt10xx/boards/imxrt1060_evk/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for IS25WP064A with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -62,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x40, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -79,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -102,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -129,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -148,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/board.c b/ports/mimxrt10xx/boards/metro_m7_1011/board.c index 27cbd3eb96..62be2303a5 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/board.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/board.c @@ -47,3 +47,18 @@ const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = { }; // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +bool mimxrt10xx_board_reset_pin_number(const mcu_pin_obj_t *pin) { + #if CIRCUITPY_SWO_TRACE + if (pin == &pin_GPIO_AD_09) { + IOMUXC_SetPinMux( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0U); + IOMUXC_SetPinConfig( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0x00F9U); + return true; + } + #endif + return false; +} diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c b/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c index b2894d7669..e4562c1965 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/flash_config.c @@ -7,48 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q32JV with QSPI routed. (compatible with GD25Q32) __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -68,13 +41,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqId = 2u, .seqNum = 1u, }, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -85,48 +58,48 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 2: Empty - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, DUMMY_SDR, FLEXSPI_1PAD, 8), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -139,17 +112,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -158,7 +131,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/pins.c b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c index 886909e1dd..675773798c 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/pins.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c @@ -38,8 +38,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_GPIO0), MP_ROM_PTR(&pin_GPIO_SD_05) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_GPIO_AD_11) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_GPIO_AD_07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO_09) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO_10) }, + // These RX and TX are from the point of view of the i.MX microcontroller. + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO_09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO_10) }, // SPI { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_AD_06) }, diff --git a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c index e0f5a5bd7d..abc26a2bcd 100644 --- a/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c +++ b/ports/mimxrt10xx/boards/sparkfun_teensy_micromod/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -64,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -81,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -104,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -131,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -150,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/teensy40/flash_config.c b/ports/mimxrt10xx/boards/teensy40/flash_config.c index d878124b40..30d40d7c84 100644 --- a/ports/mimxrt10xx/boards/teensy40/flash_config.c +++ b/ports/mimxrt10xx/boards/teensy40/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q16JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -70,13 +41,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqId = 2u, .seqNum = 1u, }, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -87,48 +58,48 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 2: Empty - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x35 /* the command to send */, DUMMY_SDR, FLEXSPI_1PAD, 8), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x02), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -141,17 +112,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -160,7 +131,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/boards/teensy41/flash_config.c b/ports/mimxrt10xx/boards/teensy41/flash_config.c index e0f5a5bd7d..abc26a2bcd 100644 --- a/ports/mimxrt10xx/boards/teensy41/flash_config.c +++ b/ports/mimxrt10xx/boards/teensy41/flash_config.c @@ -7,50 +7,21 @@ #include "boards/flash_config.h" -#include "fsl_flexspi_nor_boot.h" - - -__attribute__((section(".boot_hdr.ivt"))) -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - 0x432000D1, /* Teensy bootloader looks for this value*/ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -extern unsigned long _flashimagelen; - -__attribute__((section(".boot_hdr.boot_data"))) -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - (uint32_t)&_flashimagelen, /* actual size of image */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; +#include "xip/fsl_flexspi_nor_boot.h" // Config for W25Q64JV with QSPI routed. __attribute__((section(".boot_hdr.conf"))) const flexspi_nor_config_t qspiflash_config = { .pageSize = 256u, .sectorSize = 4u * 1024u, - .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz, + .ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz, .blockSize = 0x00010000, .isUniformBlockSize = false, .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, - .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .readSampleClkSrc = kFLEXSPIReadSampleClk_LoopbackFromDqsPad, .csHoldTime = 3u, .csSetupTime = 3u, @@ -64,13 +35,13 @@ const flexspi_nor_config_t qspiflash_config = { .seqNum = 1u, }, .deviceModeArg = 0x02, - .deviceType = kFlexSpiDeviceType_SerialNOR, + .deviceType = kFLEXSPIDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, - .serialClkFreq = kFlexSpiSerialClk_60MHz, + .serialClkFreq = kFLEXSPISerialClk_60MHz, .sflashA1Size = FLASH_SIZE, .lookupTable = { - // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) + // FSL_ROM_FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) // The high 16 bits is command 1 and the low are command 0. // Within a command, the top 6 bits are the opcode, the next two are the number // of pads and then last byte is the operand. The operand's meaning changes @@ -81,20 +52,20 @@ const flexspi_nor_config_t qspiflash_config = { // 0: ROM: Read LUTs // Quad version - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB /* the command to send */, RADDR_SDR, FLEXSPI_4PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, + FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 6 /* 6 dummy cycles, 2 for M7-0 and 4 dummy */, READ_SDR, FLEXSPI_4PAD, 0x04), // Single fast read version, good for debugging. - // FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, + // FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B /* the command to send */, // RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - // FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, + // FSL_ROM_FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 8 /* 8 dummy clocks */, // READ_SDR, FLEXSPI_1PAD, 0x04), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 1: ROM: Read status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05 /* the command to send */, READ_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -104,21 +75,21 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 3: ROM: Write Enable - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06 /* the command to send */, STOP, FLEXSPI_1PAD, 0x00), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 4: Config: Write Status - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x31 /* the command to send */, WRITE_SDR, FLEXSPI_1PAD, 0x01), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 5: ROM: Erase Sector - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, @@ -131,17 +102,17 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 8: Block Erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), // 9: ROM: Page program - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02 /* the command to send */, RADDR_SDR, FLEXSPI_1PAD, 24 /* bits to transmit */), - FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, + FSL_ROM_FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04 /* data out */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS), @@ -150,7 +121,7 @@ const flexspi_nor_config_t qspiflash_config = { EMPTY_SEQUENCE, // 11: ROM: Chip erase - SEQUENCE(FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, + SEQUENCE(FSL_ROM_FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60 /* the command to send */, STOP, FLEXSPI_1PAD, 0), TWO_EMPTY_STEPS, TWO_EMPTY_STEPS, diff --git a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c index f5d2e7f42e..237566b1f0 100644 --- a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c +++ b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c @@ -33,7 +33,7 @@ #include "py/runtime.h" -#include "fsl_adc.h" +#include "sdk/drivers/adc_12b1msps_sar/fsl_adc.h" #define ADC_CHANNEL_GROUP 0 diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index 50aae54aba..6c5bbea416 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -34,8 +34,8 @@ #include "py/runtime.h" #include "periph.h" -#include "fsl_lpi2c.h" -#include "fsl_gpio.h" +#include "sdk/drivers/lpi2c/fsl_lpi2c.h" +#include "sdk/drivers/igpio/fsl_gpio.h" #define I2C_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (1 + CLOCK_GetDiv(kCLOCK_Lpi2cDiv))) #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5 5U diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 0048c2aeb2..d88b71a403 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "periph.h" -#include "fsl_lpspi.h" +#include "sdk/drivers/lpspi/fsl_lpspi.h" #include diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index 086b8dee87..088b2aefc6 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -38,8 +38,8 @@ #include "py/stream.h" #include "periph.h" -#include "fsl_lpuart.h" -#include "fsl_gpio.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" +#include "sdk/drivers/igpio/fsl_gpio.h" // ========================================================== // Debug code // ========================================================== diff --git a/ports/mimxrt10xx/common-hal/busio/UART.h b/ports/mimxrt10xx/common-hal/busio/UART.h index bc8374aabb..f09de935c2 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.h +++ b/ports/mimxrt10xx/common-hal/busio/UART.h @@ -34,7 +34,7 @@ #include "py/obj.h" #include "periph.h" -#include "fsl_lpuart.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" typedef struct { mp_obj_base_t base; diff --git a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c index 7639204bc6..3445cf42a0 100644 --- a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +++ b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "py/mphal.h" -#include "fsl_gpio.h" +#include "sdk/drivers/igpio/fsl_gpio.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" @@ -118,7 +118,12 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( void common_hal_digitalio_digitalinout_set_value( digitalio_digitalinout_obj_t *self, bool value) { - GPIO_PinWrite(self->pin->gpio, self->pin->number, value); + GPIO_Type *gpio = self->pin->gpio; + if (value) { + gpio->DR_SET = 1 << self->pin->number; + } else { + gpio->DR_CLEAR = 1 << self->pin->number; + } } bool common_hal_digitalio_digitalinout_get_value( diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c index 17ced78910..9277f81d47 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c @@ -33,8 +33,8 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" -#include "fsl_tempmon.h" -#include "fsl_ocotp.h" +#include "sdk/drivers/tempmon/fsl_tempmon.h" +#include "sdk/drivers/ocotp/fsl_ocotp.h" #include "clocks.h" float common_hal_mcu_processor_get_temperature(void) { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 5388f404de..1b10b4d4ee 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -36,6 +36,7 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/linker.h" #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/translate/translate.h" @@ -43,14 +44,14 @@ void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } -volatile uint32_t nesting_count = 0; -void common_hal_mcu_disable_interrupts(void) { +volatile uint32_t PLACE_IN_DTCM_BSS(nesting_count) = 0; +void PLACE_IN_ITCM(common_hal_mcu_disable_interrupts)(void) { __disable_irq(); __DMB(); nesting_count++; } -void common_hal_mcu_enable_interrupts(void) { +void PLACE_IN_ITCM(common_hal_mcu_enable_interrupts)(void) { if (nesting_count == 0) { // This is very very bad because it means there was mismatched disable/enables reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); diff --git a/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c b/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c index c757a28e6e..a26c34ce32 100644 --- a/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c +++ b/ports/mimxrt10xx/common-hal/neopixel_write/__init__.c @@ -64,9 +64,7 @@ void PLACE_IN_ITCM(common_hal_neopixel_write)(const digitalio_digitalinout_obj_t const uint32_t pin = digitalinout->pin->number; __disable_irq(); - // Enable DWT in debug core. Usable when interrupts disabled, as opposed to Systick->VAL - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + // Use DWT in debug core. Usable when interrupts disabled, as opposed to Systick->VAL DWT->CYCCNT = 0; for (;;) { @@ -88,12 +86,12 @@ void PLACE_IN_ITCM(common_hal_neopixel_write)(const digitalio_digitalinout_obj_t mask = 0x80; } } + // Enable interrupts again + __enable_irq(); // Update the next start. next_start_raw_ticks = port_get_raw_ticks(NULL) + 4; - // Enable interrupts again - __enable_irq(); } #pragma GCC pop_options diff --git a/ports/mimxrt10xx/common-hal/os/__init__.c b/ports/mimxrt10xx/common-hal/os/__init__.c index e2c43e43fa..9219242685 100644 --- a/ports/mimxrt10xx/common-hal/os/__init__.c +++ b/ports/mimxrt10xx/common-hal/os/__init__.c @@ -33,7 +33,7 @@ #include "shared-bindings/os/__init__.h" -#include "fsl_trng.h" +#include "sdk/drivers/trng/fsl_trng.h" STATIC const qstr os_uname_info_fields[] = { MP_QSTR_sysname, MP_QSTR_nodename, diff --git a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c index c2afb38664..0bf11403d2 100644 --- a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +++ b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -33,7 +33,7 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "shared-bindings/microcontroller/Pin.h" -#include "fsl_pwm.h" +#include "sdk/drivers/pwm/fsl_pwm.h" #include "supervisor/shared/translate/translate.h" #include "periph.h" @@ -240,7 +240,6 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, // Disable all fault inputs flexpwm->SM[submodule].DISMAP[0] = 0; - flexpwm->SM[submodule].DISMAP[1] = 0; PWM_SetPwmLdok(flexpwm, sm_mask, false); flexpwm->SM[submodule].CTRL = PWM_CTRL_FULL_MASK | PWM_CTRL_PRSC(self->prescaler); diff --git a/ports/mimxrt10xx/common-hal/rtc/RTC.c b/ports/mimxrt10xx/common-hal/rtc/RTC.c index 0cf5fe7713..386b6a3ac5 100644 --- a/ports/mimxrt10xx/common-hal/rtc/RTC.c +++ b/ports/mimxrt10xx/common-hal/rtc/RTC.c @@ -35,8 +35,8 @@ #include "common-hal/rtc/RTC.h" #include "supervisor/shared/translate/translate.h" -#include "fsl_snvs_hp.h" -#include "fsl_snvs_lp.h" +#include "sdk/drivers/snvs_hp/fsl_snvs_hp.h" +#include "sdk/drivers/snvs_lp/fsl_snvs_lp.h" void rtc_init(void) { snvs_hp_rtc_config_t hpconfig; diff --git a/ports/mimxrt10xx/linking/common.ld b/ports/mimxrt10xx/linking/common.ld index b6f1acc8d0..76c11c8d6f 100644 --- a/ports/mimxrt10xx/linking/common.ld +++ b/ports/mimxrt10xx/linking/common.ld @@ -6,7 +6,7 @@ Boards can setup reserved flash with _ld_reserved_flash_size in board.ld. */ ENTRY(Reset_Handler) -code_size = 1M; +code_size = _ld_flash_size >= 4M ? 2M : 1M; _ld_default_stack_size = 20K; /* Default reserved flash to nothing. */ @@ -22,9 +22,9 @@ MEMORY FLASH_IVT (rx) : ORIGIN = 0x60001000, LENGTH = 4K /* Place the ISRs 48k in to leave room for the bootloader when it is available. */ FLASH_FIRMWARE (rx) : ORIGIN = 0x6000C000, LENGTH = code_size - 48K - FLASH_FATFS (r) : ORIGIN = 0x60100000, LENGTH = _ld_flash_size - code_size - _ld_reserved_flash_size + FLASH_FATFS (r) : ORIGIN = 0x60000000 + code_size, LENGTH = _ld_flash_size - code_size - _ld_reserved_flash_size /* Teensy uses the last bit of flash for recovery. */ - RESERVED_FLASH : ORIGIN = 0x60100000 + _ld_flash_size - _ld_reserved_flash_size, LENGTH = _ld_reserved_flash_size + RESERVED_FLASH : ORIGIN = 0x60000000 + code_size + _ld_flash_size - _ld_reserved_flash_size, LENGTH = _ld_reserved_flash_size OCRAM (rwx) : ORIGIN = 0x20200000, LENGTH = ram_size - 64K DTCM (x) : ORIGIN = 0x20000000, LENGTH = 32K ITCM (x) : ORIGIN = 0x00000000, LENGTH = 32K @@ -52,24 +52,59 @@ SECTIONS . = ALIGN(4); } > FLASH_IVT + /* Align for 256 ISR entries and place first in flash. Otherwise the UF2 + bootloader can't find it because it uses its own flash_config and ivt. */ + .isr_vector : ALIGN(4 * 256) + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > ITCM AT> FLASH_FIRMWARE + _ld_isr_destination = ADDR(.isr_vector); + _ld_isr_flash_copy = LOADADDR(.isr_vector); + _ld_isr_size = SIZEOF(.isr_vector); + /* Used by the bootloader to start user code. */ + __VECTOR_TABLE = LOADADDR(.isr_vector); + .text : { . = ALIGN(4); - __VECTOR_TABLE = .; - __VECTOR_RAM = .; - _ld_isr_table = .; - - KEEP(*(.isr_vector)) /* Startup code */ *(EXCLUDE_FILE( *fsl_flexspi.o + *dcd_ci_hs.o + *tusb_fifo.o + *usbd.o + *string0.o + *py/nlr*.o + *py/obj.o + *py/gc.o + *py/map.o + *py/runtime.o + *py/objboundmeth.o + *py/objtype.o ) .text*) /* .text* sections (code) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + /* Keep USB processing functions out of RAM because we don't know which will be used. + We try to only keep USB interrupt related functions. */ + *dcd_ci_hs.o(.text.process_*_request .text.dcd_edpt* .text.dcd_init .text.dcd_set_address) + *usbd.o(.text.process_*_request .text.process_[gs]et* .text.tud_* .text.usbd_* .text.configuration_reset .text.invoke_*) + + /* Anything marked cold/unlikely should be in flash. */ + *(.text.unlikely.*) + + *(EXCLUDE_FILE( + *dcd_ci_hs.o + *py/objboundmeth.o + *py/objtype.o + ) .rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } > FLASH_FIRMWARE .ARM.exidx : { + __exidx_start = .; *(.ARM.exidx*) + __exidx_end = .; *(.gnu.linkonce.armexidx.*) _etext = .; /* define a global symbol at end of code */ __etext = .; /* define a global symbol at end of code */ @@ -81,7 +116,6 @@ SECTIONS { . = ALIGN(4); *(.data*) /* .data* sections */ - *fsl_flexspi.o(.text*) . = ALIGN(4); } > OCRAM AT> FLASH_FIRMWARE _ld_ocram_data_destination = ADDR(.data); @@ -93,7 +127,7 @@ SECTIONS { . = ALIGN(4); - *(.bss*) + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) *(COMMON) . = ALIGN(4); @@ -103,11 +137,23 @@ SECTIONS _ld_heap_start = _ld_ocram_bss_start + _ld_ocram_bss_size; _ld_heap_end = ORIGIN(OCRAM) + LENGTH(OCRAM); - .itcm : + + .itcm : ALIGN(4) { . = ALIGN(4); *(.itcm.*) - + *fsl_flexspi.o(.text*) + *dcd_ci_hs.o(.text*) + *tusb_fifo.o(.text*) + *py/objboundmeth.o(.text*) + *py/objtype.o(.text*) + *py/obj.o(.text*) + *py/gc.o(.text*) + *py/map.o(.text*) + *py/nlr*.o(.text*) + *py/runtime.o(.text*) + *(.text.process_*_isr .text.dcd_event_* .text.osal_queue*) + *string0.o(.text*) . = ALIGN(4); } > ITCM AT> FLASH_FIRMWARE _ld_itcm_destination = ADDR(.itcm); @@ -119,6 +165,9 @@ SECTIONS . = ALIGN(4); *(.dtcm_data.*) + *dcd_ci_hs.o(.rodata*) + *py/objboundmeth.o(.rodata*) + *py/objtype.o(.rodata*) . = ALIGN(4); } > DTCM AT> FLASH_FIRMWARE @@ -139,13 +188,15 @@ SECTIONS _ld_dtcm_bss_start = ADDR(.dtcm_bss); _ld_dtcm_bss_size = SIZEOF(.dtcm_bss); - .stack : + .stack (NOLOAD) : { . = ALIGN(8); _ld_stack_bottom = .; . += _ld_default_stack_size; } > DTCM _ld_stack_top = ORIGIN(DTCM) + LENGTH(DTCM); + /* For the SDK's isr vector table */ + __StackTop = ORIGIN(DTCM) + LENGTH(DTCM); .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk index cee2d9a698..236d5b9966 100644 --- a/ports/mimxrt10xx/mpconfigport.mk +++ b/ports/mimxrt10xx/mpconfigport.mk @@ -6,6 +6,8 @@ USB_HIGHSPEED = 1 # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 +# Align buffers on the cache boundary so we don't inadvertently load them early. +CIRCUITPY_TUSB_MEM_ALIGN = 32 INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/mimxrt10xx/mphalport.c b/ports/mimxrt10xx/mphalport.c index ad0fb4d9ba..f160cf1365 100644 --- a/ports/mimxrt10xx/mphalport.c +++ b/ports/mimxrt10xx/mphalport.c @@ -35,11 +35,7 @@ #include "fsl_common.h" void mp_hal_delay_us(mp_uint_t delay) { - #if defined(MIMXRT1011_SERIES) || defined(MIMXRT1021_SERIES) SDK_DelayAtLeastUs(delay, SystemCoreClock); - #else - SDK_DelayAtLeastUs(delay); - #endif } void mp_hal_disable_all_interrupts(void) { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h index d6d12771c5..82cb0dc69e 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/pins.h @@ -35,7 +35,7 @@ #include #include "fsl_iomuxc.h" -#include "fsl_pwm.h" +#include "sdk/drivers/pwm/fsl_pwm.h" #include "py/obj.h" extern const mp_obj_type_t mcu_pin_type; diff --git a/ports/mimxrt10xx/reset.c b/ports/mimxrt10xx/reset.c index a3a4f667de..3d9a0b071b 100644 --- a/ports/mimxrt10xx/reset.c +++ b/ports/mimxrt10xx/reset.c @@ -26,10 +26,11 @@ #include "reset.h" #include "supervisor/filesystem.h" +#include "supervisor/linker.h" #include "fsl_common.h" -void reset(void) { +void PLACE_IN_ITCM(reset)(void) { filesystem_flush(); NVIC_SystemReset(); } diff --git a/ports/mimxrt10xx/sdk b/ports/mimxrt10xx/sdk index 8363ff7bed..2b9354539e 160000 --- a/ports/mimxrt10xx/sdk +++ b/ports/mimxrt10xx/sdk @@ -1 +1 @@ -Subproject commit 8363ff7bed7533b9e7e6a6239aace3d6da14f349 +Subproject commit 2b9354539e6e4f722749e87b0bdc22966dc080d9 diff --git a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c index 950e9aa403..e32eaf8832 100644 --- a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c +++ b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c @@ -7,12 +7,23 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "fsl_flexspi.h" +#include "sdk/drivers/flexspi/fsl_flexspi.h" #include "internal_flash.h" #include "boards/flash_config.h" #include "supervisor/internal_flash.h" #include "supervisor/linker.h" +STATIC uint8_t _busy_bit_shift; +STATIC bool _busy_bit_polarity; +STATIC bool _inited = false; + +void flexspi_nor_init(void) { + // Copy busy bit info into RAM so we can use if when flash isn't available. + _busy_bit_shift = qspiflash_config.memConfig.busyOffset; + _busy_bit_polarity = qspiflash_config.memConfig.busyBitPolarity; + _inited = true; +} + STATIC status_t PLACE_IN_ITCM(flexspi_nor_write_enable)(FLEXSPI_Type * base, uint32_t baseAddr) { flexspi_transfer_t flashXfer; @@ -53,9 +64,8 @@ STATIC status_t PLACE_IN_ITCM(flexspi_nor_wait_bus_busy)(FLEXSPI_Type * base) if (status != kStatus_Success) { return status; } - size_t busyBit = readValue & (1U << qspiflash_config.memConfig.busyOffset); - isBusy = (qspiflash_config.memConfig.busyBitPolarity == 0 && busyBit != 0) || - (qspiflash_config.memConfig.busyBitPolarity == 1 && busyBit == 0); + bool busyBit = (readValue >> _busy_bit_shift) & 0x1; + isBusy = busyBit != _busy_bit_polarity; } while (isBusy); return status; diff --git a/ports/mimxrt10xx/supervisor/internal_flash.c b/ports/mimxrt10xx/supervisor/internal_flash.c index 72d57d1dd4..bacb62854a 100644 --- a/ports/mimxrt10xx/supervisor/internal_flash.c +++ b/ports/mimxrt10xx/supervisor/internal_flash.c @@ -38,8 +38,8 @@ #include "py/runtime.h" #include "lib/oofatfs/ff.h" -#include "fsl_cache.h" -#include "fsl_flexspi.h" +#include "sdk/drivers/cache/armv7-m7/fsl_cache.h" +#include "sdk/drivers/flexspi/fsl_flexspi.h" #include "fsl_iomuxc.h" // defined in linker @@ -53,8 +53,15 @@ uint8_t _flash_cache[SECTOR_SIZE] __attribute__((aligned(4))); uint32_t _flash_page_addr = NO_CACHE; void PLACE_IN_ITCM(supervisor_flash_init)(void) { - // Update the LUT to make sure all entries are available. - FLEXSPI_UpdateLUT(FLEXSPI, 0, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64); + // Update the LUT to make sure all entries are available. Copy the values to + // memory first so that we don't read from the flash as we update the LUT. + uint32_t lut_copy[64]; + memcpy(lut_copy, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64 * sizeof(uint32_t)); + FLEXSPI_UpdateLUT(FLEXSPI, 0, lut_copy, 64); + // Make sure everything is flushed after updating the LUT. + __DSB(); + __ISB(); + flexspi_nor_init(); } static inline uint32_t lba2addr(uint32_t block) { @@ -79,20 +86,21 @@ void PLACE_IN_ITCM(port_internal_flash_flush)(void) { if (memcmp(_flash_cache, (void *)_flash_page_addr, SECTOR_SIZE) != 0) { volatile uint32_t sector_addr = (_flash_page_addr - FlexSPI_AMBA_BASE); - __disable_irq(); + // Disable interrupts of priority 8+. They likely use code in flash + // itself. Higher priority interrupts (<8) should ensure all of their + // code is in RAM. + __set_BASEPRI(8 << (8 - __NVIC_PRIO_BITS)); status = flexspi_nor_flash_erase_sector(FLEXSPI, sector_addr); - __enable_irq(); + __set_BASEPRI(0U); if (status != kStatus_Success) { - printf("Page erase failure %ld!\r\n", status); return; } for (int i = 0; i < SECTOR_SIZE / FLASH_PAGE_SIZE; ++i) { - __disable_irq(); + __set_BASEPRI(8 << (8 - __NVIC_PRIO_BITS)); status = flexspi_nor_flash_page_program(FLEXSPI, sector_addr + i * FLASH_PAGE_SIZE, (void *)_flash_cache + i * FLASH_PAGE_SIZE); - __enable_irq(); + __set_BASEPRI(0U); if (status != kStatus_Success) { - printf("Page program failure %ld!\r\n", status); return; } } @@ -103,11 +111,17 @@ void PLACE_IN_ITCM(port_internal_flash_flush)(void) { } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { - // Must write out anything in cache before trying to read. - supervisor_flash_flush(); + for (size_t i = 0; i < num_blocks; i++) { + uint32_t src = lba2addr(block + i); + uint32_t page_addr = src & ~(SECTOR_SIZE - 1); + // Copy from the cache if our page matches the cached one. + if (page_addr == _flash_page_addr) { + src = ((uint32_t)&_flash_cache) + (src - page_addr); + } + + memcpy(dest + FILESYSTEM_BLOCK_SIZE * i, (uint8_t *)src, FILESYSTEM_BLOCK_SIZE); + } - uint32_t src = lba2addr(block); - memcpy(dest, (uint8_t *)src, FILESYSTEM_BLOCK_SIZE * num_blocks); return 0; // success } @@ -141,5 +155,5 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32 return 0; // success } -void supervisor_flash_release_cache(void) { +void PLACE_IN_ITCM(supervisor_flash_release_cache)(void) { } diff --git a/ports/mimxrt10xx/supervisor/internal_flash.h b/ports/mimxrt10xx/supervisor/internal_flash.h index 66d3f73db1..c38e2bc416 100644 --- a/ports/mimxrt10xx/supervisor/internal_flash.h +++ b/ports/mimxrt10xx/supervisor/internal_flash.h @@ -42,6 +42,7 @@ #define ROM_INDEX_PAGEPROGRAM 9 #define ROM_INDEX_READSTATUSREG 1 +extern void flexspi_nor_init(void); extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src); extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base); diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index 6997b4bae5..55bf72352d 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -42,19 +42,20 @@ #include "common-hal/busio/SPI.h" #include "shared-bindings/microcontroller/__init__.h" -#include "reset.h" - -#include "supervisor/background_callback.h" - #if CIRCUITPY_PEW #include "shared-module/_pew/PewPew.h" #endif + +#include "reset.h" + +#include "supervisor/background_callback.h" +#include "supervisor/linker.h" #include "supervisor/shared/tick.h" #include "clocks.h" -#include "fsl_gpio.h" -#include "fsl_lpuart.h" +#include "sdk/drivers/igpio/fsl_gpio.h" +#include "sdk/drivers/lpuart/fsl_lpuart.h" // Device memories must be accessed in order. #define DEVICE 2 @@ -97,16 +98,55 @@ extern uint32_t _ld_dtcm_data_flash_copy; extern uint32_t _ld_itcm_destination; extern uint32_t _ld_itcm_size; extern uint32_t _ld_itcm_flash_copy; +extern uint32_t _ld_isr_destination; +extern uint32_t _ld_isr_size; +extern uint32_t _ld_isr_flash_copy; + +// Remove these once the SDK re-includes them. +// https://github.com/nxp-mcuxpresso/mcux-sdk/issues/110 +/*! @name GPR14 - GPR14 General Purpose Register */ +/*! @{ */ +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK (0xF0000U) +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_SHIFT (16U) +/*! CM7_CFGITCMSZ + * 0b0000..0 KB (No ITCM) + * 0b0011..4 KB + * 0b0100..8 KB + * 0b0101..16 KB + * 0b0110..32 KB + * 0b0111..64 KB + * 0b1000..128 KB + */ +#define IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_SHIFT)) & IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK) +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK (0xF00000U) +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_SHIFT (20U) +/*! CM7_CFGDTCMSZ + * 0b0000..0 KB (No DTCM) + * 0b0011..4 KB + * 0b0100..8 KB + * 0b0101..16 KB + * 0b0110..32 KB + * 0b0111..64 KB + * 0b1000..128 KB + */ +#define IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ(x) (((uint32_t)(((uint32_t)(x)) << IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_SHIFT)) & IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK) +/*! @} */ extern void main(void); // This replaces the Reset_Handler in startup_*.S and SystemInit in system_*.c. +// Turn off optimize("no-tree-loop-distribute-patterns") so that this isn't replaced +// by calls to memcpy because we're copying it over now. void Reset_Handler(void); -__attribute__((used, naked)) void Reset_Handler(void) { +__attribute__((used, naked, no_instrument_function, optimize("no-tree-loop-distribute-patterns"))) void Reset_Handler(void) { __disable_irq(); - SCB->VTOR = (uint32_t)&__isr_vector; + // Set the VTOR to the flash copy since we haven't copied it into RAM. + SCB->VTOR = (uint32_t)&_ld_isr_flash_copy; __set_MSP((uint32_t)&_ld_stack_top); + // Turn off any residual ITM outputs. + ITM->TER = 0; + /* Disable I cache and D cache */ SCB_DisableICache(); SCB_DisableDCache(); @@ -128,6 +168,11 @@ __attribute__((used, naked)) void Reset_Handler(void) { current_gpr14 |= IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(0x6); IOMUXC_GPR->GPR14 = current_gpr14; + // Enable FlexRAM interrupts on invalid access. + FLEXRAM->INT_STAT_EN = FLEXRAM_INT_STAT_EN_ITCM_ERR_STAT_EN(1) | + FLEXRAM_INT_STAT_EN_DTCM_ERR_STAT_EN(1) | + FLEXRAM_INT_STAT_EN_OCRAM_ERR_STAT_EN(1); + #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access */ #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ @@ -157,6 +202,13 @@ __attribute__((used, naked)) void Reset_Handler(void) { (&_ld_itcm_destination)[i] = (&_ld_itcm_flash_copy)[i]; } + for (uint32_t i = 0; i < ((size_t)&_ld_isr_size) / 4; i++) { + (&_ld_isr_destination)[i] = (&_ld_isr_flash_copy)[i]; + } + + // Now that we've copied the ISR table over, use that VTOR. + SCB->VTOR = (uint32_t)&_ld_isr_destination; + // The first number in RBAR is the region number. When searching for a policy, the region with // the highest number wins. If none match, then the default policy set at enable applies. @@ -170,14 +222,19 @@ __attribute__((used, naked)) void Reset_Handler(void) { // FlexSPI2 is 0x70000000 - // This the first 1MB of flash is the bootloader and CircuitPython read-only data. - MPU->RBAR = ARM_MPU_RBAR(10, 0x60000000U); - MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_1MB); + // This the first portion (1MB, 2MB or 4MB) of flash is the bootloader and CircuitPython read-only data. + MPU->RBAR = ARM_MPU_RBAR(10, FlexSPI_AMBA_BASE); + uint32_t region_size = ARM_MPU_REGION_SIZE_32B; + uint32_t code_size = ((uint32_t)&_ld_filesystem_start) - FlexSPI_AMBA_BASE; + while (code_size > (1u << (region_size + 1))) { + region_size += 1; + } + MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, region_size); // The remainder of flash is the fat filesystem which could have code on it too. Make sure that // we set the region to the minimal size so that bad data doesn't get speculatively fetched. // Thanks to Damien for the tip! - uint32_t region_size = ARM_MPU_REGION_SIZE_32B; + region_size = ARM_MPU_REGION_SIZE_32B; uint32_t filesystem_size = &_ld_filesystem_end - &_ld_filesystem_start; while (filesystem_size > (1u << (region_size + 1))) { region_size += 1; @@ -189,7 +246,7 @@ __attribute__((used, naked)) void Reset_Handler(void) { uint32_t subregion_size = (1u << (region_size + 1)) / 8; uint8_t subregion_mask = (0xff00 >> (remainder / subregion_size)) & 0xff; - MPU->RBAR = ARM_MPU_RBAR(11, 0x60100000U); + MPU->RBAR = ARM_MPU_RBAR(11, (size_t)&_ld_filesystem_start); MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, subregion_mask, region_size); // This the ITCM. Set it to read-only because we've loaded everything already and it's easy to @@ -205,9 +262,10 @@ __attribute__((used, naked)) void Reset_Handler(void) { // cost of 1/4 speed OCRAM accesses. It will leave more room for caching data from the flash // too which might be a net win. MPU->RBAR = ARM_MPU_RBAR(14, 0x20200000U); - MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512KB); + MPU->RASR = ARM_MPU_RASR(NO_EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, NO_SUBREGIONS, ARM_MPU_REGION_SIZE_512KB); // We steal 64k from FlexRAM for ITCM and DTCM so disable those memory regions here. + // We use 64k from FlexRAM for ITCM and DTCM so disable those memory regions here. MPU->RBAR = ARM_MPU_RBAR(15, 0x20280000U); MPU->RASR = ARM_MPU_RASR(EXECUTION, ARM_MPU_AP_FULL, NORMAL, NOT_SHAREABLE, CACHEABLE, BUFFERABLE, 0x80, ARM_MPU_REGION_SIZE_512KB); @@ -239,14 +297,97 @@ __attribute__((used, naked)) void Reset_Handler(void) { } __enable_irq(); + main(); } +void __attribute__((no_instrument_function,section(".itcm.profile_enter"),long_call)) __cyg_profile_func_enter(void *this_fn, + void *call_site) { + if ((ITM->TER & (1 << 3)) == 0) { + return; + } + uint32_t addr = (uint32_t)this_fn; + while (ITM->PORT[3U].u32 == 0UL) { + // addr |= 1; + } + ITM->PORT[3].u32 = addr; +} + +void __attribute__((no_instrument_function,section(".itcm.profile_exit"),long_call)) __cyg_profile_func_exit(void *this_fn, + void *call_site) { + if ((ITM->TER & (1 << 4)) == 0) { + return; + } + uint32_t addr = (uint32_t)this_fn; + while (ITM->PORT[4U].u32 == 0UL) { + // addr |= 1; + } + ITM->PORT[4].u32 = addr; +} + safe_mode_t port_init(void) { CLOCK_SetMode(kCLOCK_ModeRun); clocks_init(); + // Turn on the DWT so that neopixel_write can use CYCCNT for timing. + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL = 0x2 << DWT_CTRL_SYNCTAP_Pos | DWT_CTRL_CYCCNTENA_Msk; + + // Enable SWO if needed. + #if CIRCUITPY_SWO_TRACE + + // Turn on the 528 MHz clock to the TPIU. + CLOCK_EnableClock(kCLOCK_Trace); /* Make these edits*/ + /* Set TRACE_PODF. */ + CLOCK_SetDiv(kCLOCK_TraceDiv, 0); /* Make these edits*/ + /* Set Trace clock source. */ + CLOCK_SetMux(kCLOCK_TraceMux, 0); /* Make these edits*/ + + ITM->TCR = ITM_TCR_TSENA_Msk | ITM_TCR_ITMENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_DWTENA_Msk; + + // Run at 2.75 mbaud. CP2102N says it can do up to 3. + // Base clock is 528 mhz (not 500 like the core). + // TPI->ACPR = 191; + // Run at 1 mbaud so that USB isn't bottlenecked. + TPI->ACPR = 527; + TPI->SPPR = 0x2; // NRZ aka UART + TPI->FFCR = 0; + + IOMUXC_SetPinMux( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0U); + IOMUXC_SetPinConfig( /* Add these lines*/ + IOMUXC_GPIO_AD_09_ARM_TRACE_SWO, + 0x00F9U); + + // Enable ports 0-4: + // * 0 is serial output + // * + // * 3 is addresses of functions beginning. + // * 4 is addresses of functions ending. + ITM->TER |= 0x1f; + ITM->PORT[0].u8 = 'C'; + ITM->PORT[0].u8 = 'P'; + ITM->PORT[0].u8 = '\n'; + #endif + + // Set all peripheral interrupt priorities to the lowest priority by default. + for (uint16_t i = 0; i < NUMBER_OF_INT_VECTORS; i++) { + NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL); + } + NVIC_SetPriority(USB_OTG1_IRQn, 1); + #ifdef USBPHY2 + NVIC_SetPriority(USB_OTG2_IRQn, 1); + #endif + + NVIC_SetPriority(FLEXRAM_IRQn, 0); + NVIC_EnableIRQ(FLEXRAM_IRQn); + + // Priorities 8+ will be disabled during flash operations. To run during + // flash operations, ensure all code is in RAM (not flash) and set the + // priority < 8. + #if CIRCUITPY_RTC rtc_init(); #endif @@ -305,7 +446,7 @@ void reset_to_bootloader(void) { reset(); } -void reset_cpu(void) { +void PLACE_IN_ITCM(reset_cpu)(void) { reset(); } @@ -332,7 +473,7 @@ uint32_t *port_heap_get_top(void) { } // Place the word into the low power section of the SNVS. -void port_set_saved_word(uint32_t value) { +void PLACE_IN_ITCM(port_set_saved_word)(uint32_t value) { SNVS->LPGPR[1] = value; } @@ -355,7 +496,7 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { void SNVS_HP_WRAPPER_IRQHandler(void); __attribute__((used)) -void SNVS_HP_WRAPPER_IRQHandler(void) { +void PLACE_IN_ITCM(SNVS_HP_WRAPPER_IRQHandler)(void) { if ((SNVS->HPSR & SNVS_HPSR_PI_MASK) != 0) { supervisor_tick(); SNVS->HPSR = SNVS_HPSR_PI_MASK; @@ -414,44 +555,43 @@ void port_idle_until_interrupt(void) { common_hal_mcu_enable_interrupts(); } -/** - * \brief Default interrupt handler for unused IRQs. - */ +// Catch faults where the memory access violates MPU settings. void MemManage_Handler(void); -__attribute__((used)) void MemManage_Handler(void) { +__attribute__((used)) void PLACE_IN_ITCM(MemManage_Handler)(void) { reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ void BusFault_Handler(void); -__attribute__((used)) void BusFault_Handler(void) { +__attribute__((used)) void PLACE_IN_ITCM(BusFault_Handler)(void) { reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ void UsageFault_Handler(void); -__attribute__((used)) void UsageFault_Handler(void) { +__attribute__((used)) void PLACE_IN_ITCM(UsageFault_Handler)(void) { reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); } } -/** - * \brief Default interrupt handler for unused IRQs. - */ +// Default fault handler. void HardFault_Handler(void); -__attribute__((used)) void HardFault_Handler(void) { +__attribute__((used)) void PLACE_IN_ITCM(HardFault_Handler)(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +// Catch access errors to FlexRAM (if the MPU didn't catch it first.) +void FLEXRAM_IRQHandler(void); +__attribute__((used)) void PLACE_IN_ITCM(FLEXRAM_IRQHandler)(void) { reset_into_safe_mode(SAFE_MODE_HARD_FAULT); while (true) { asm ("nop;"); diff --git a/ports/mimxrt10xx/supervisor/serial.c b/ports/mimxrt10xx/supervisor/serial.c deleted file mode 100644 index cb557d36a8..0000000000 --- a/ports/mimxrt10xx/supervisor/serial.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2019 Lucian Copeland for Adafruit Industries - * Copyright (c) 2019 Artur Pacholec - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "supervisor/serial.h" -#include "py/mphal.h" -#include - -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -#if defined(CIRCUITPY_CONSOLE_UART) -// static LPUART_Type *uart_instance = LPUART1; // evk -static LPUART_Type *uart_instance = LPUART4; // feather 1011 -// static LPUART_Type *uart_instance = LPUART2; // feather 1062 -static uint32_t UartSrcFreq(void) { - uint32_t freq; - - /* To make it simple, we assume default PLL and divider settings, and the only - variable from application is use PLL3 source or OSC source */ - /* PLL3 div6 80M */ - if (CLOCK_GetMux(kCLOCK_UartMux) == 0) { - freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / - (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } else { - freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); - } - - return freq; -} - -void port_serial_init(void) { - lpuart_config_t config; - - LPUART_GetDefaultConfig(&config); - config.baudRate_Bps = 115200; - config.enableTx = true; - config.enableRx = true; - - LPUART_Init(uart_instance, &config, UartSrcFreq()); -} - -bool port_serial_connected(void) { - return true; -} - -char port_serial_read(void) { - uint8_t data; - - LPUART_ReadBlocking(uart_instance, &data, sizeof(data)); - - return data; -} - -bool port_serial_bytes_available(void) { - return LPUART_GetStatusFlags(uart_instance) & kLPUART_RxDataRegFullFlag; -} - -void port_serial_write_substring(const char *text, uint32_t len) { - if (len == 0) { - return; - } - - LPUART_WriteBlocking(uart_instance, (uint8_t *)text, len); -} -#endif // CIRCUITPY_CONSOLE_UART diff --git a/ports/mimxrt10xx/supervisor/usb.c b/ports/mimxrt10xx/supervisor/usb.c index 2094a943b5..bc6bc5f0cd 100644 --- a/ports/mimxrt10xx/supervisor/usb.c +++ b/ports/mimxrt10xx/supervisor/usb.c @@ -27,6 +27,8 @@ #include "fsl_clock.h" #include "tusb.h" + +#include "supervisor/linker.h" #include "supervisor/usb.h" STATIC void init_usb_instance(mp_int_t instance) { @@ -78,13 +80,13 @@ STATIC void init_usb_instance(mp_int_t instance) { // Provide the prototypes for the interrupt handlers. The iMX RT SDK doesn't. // The SDK only links to them from assembly. void USB_OTG1_IRQHandler(void); - void USB_OTG1_IRQHandler(void) { + void PLACE_IN_ITCM(USB_OTG1_IRQHandler)(void) { usb_irq_handler(0); } #ifdef USBPHY2 void USB_OTG2_IRQHandler(void); - void USB_OTG2_IRQHandler(void) { + void PLACE_IN_ITCM(USB_OTG2_IRQHandler)(void) { usb_irq_handler(1); } #endif diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index ada9f46020..bbf076ba68 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -341,7 +341,10 @@ STATIC mp_obj_t rp2pio_statemachine_run(mp_obj_t self_obj, mp_obj_t instruction_ mp_buffer_info_t bufinfo; mp_get_buffer_raise(instruction_obj, &bufinfo, MP_BUFFER_READ); - common_hal_rp2pio_statemachine_run(self, bufinfo.buf, bufinfo.len); + if (bufinfo.len % 2 != 0) { + mp_raise_ValueError(translate("Program size invalid")); + } + common_hal_rp2pio_statemachine_run(self, bufinfo.buf, (size_t)bufinfo.len / 2); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(rp2pio_statemachine_run_obj, rp2pio_statemachine_run); diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/board.c new file mode 100644 index 0000000000..331653173e --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/board.c @@ -0,0 +1,29 @@ +/* + * 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" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.h new file mode 100644 index 0000000000..356f0f5b54 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.h @@ -0,0 +1,15 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2040 EPD" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO20) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.mk new file mode 100644 index 0000000000..3b457b93cb --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x239A +USB_PID = 0x812C +USB_PRODUCT = "Feather RP2040 EPD" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pico-sdk-configboard.h new file mode 100644 index 0000000000..a41131dd22 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/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_feather_rp2040_epd/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pins.c new file mode 100644 index 0000000000..22ae43adad --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_epd/pins.c @@ -0,0 +1,51 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RESET), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_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_module_globals_table); diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index e2b82264ba..fe12f461fb 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -1109,7 +1109,7 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *socket, break; } if (ret == (unsigned)-1) { - mp_raise_OSError(_errno); + return -_errno; } return ret; } diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index c94845229c..237b99bfe8 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -194,6 +194,8 @@ extern const struct _mp_print_t mp_stderr_print; +#define RUN_BACKGROUND_TASKS + #if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) // Fall back to setjmp() implementation for discovery of GC pointers in registers. #define MICROPY_GCREGS_SETJMP (1) diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index ba9e941c28..0c6e10aeae 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -62,6 +62,7 @@ #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#define MICROPY_PY_STRUCT (0) // uses shared-bindings struct #define MICROPY_PY_UCRYPTOLIB (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index fd12bbd8b5..20320916bc 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -33,6 +33,7 @@ SRC_BITMAP := \ shared-bindings/bitmaptools/__init__.c \ shared-bindings/displayio/Bitmap.c \ shared-bindings/rainbowio/__init__.c \ + shared-bindings/struct/__init__.c \ shared-bindings/traceback/__init__.c \ shared-bindings/util.c \ shared-bindings/zlib/__init__.c \ @@ -45,6 +46,7 @@ SRC_BITMAP := \ shared-module/displayio/ColorConverter.c \ shared-module/os/getenv.c \ shared-module/rainbowio/__init__.c \ + shared-module/struct/__init__.c \ shared-module/traceback/__init__.c \ shared-module/zlib/__init__.c \ @@ -57,6 +59,7 @@ CFLAGS += \ -DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_GIFIO=1 \ -DCIRCUITPY_RAINBOWIO=1 \ + -DCIRCUITPY_STRUCT=1 \ -DCIRCUITPY_TRACEBACK=1 \ -DCIRCUITPY_ZLIB=1 diff --git a/py/argcheck.c b/py/argcheck.c index 05c2567ca2..465a82c97e 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -31,7 +31,7 @@ #include "supervisor/shared/translate/translate.h" -void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { +void PLACE_IN_ITCM(mp_arg_check_num_sig)(size_t n_args, size_t n_kw, uint32_t sig) { // TODO maybe take the function name as an argument so we can print nicer error messages // The reverse of MP_OBJ_FUN_MAKE_SIG diff --git a/py/bc.c b/py/bc.c index e1645dbff0..e7ad43389a 100644 --- a/py/bc.c +++ b/py/bc.c @@ -111,7 +111,7 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) { // - code_state->fun_bc should contain a pointer to the function object // - code_state->ip should contain the offset in bytes from the pointer // code_state->fun_bc->bytecode to the entry n_state (0 for bytecode, non-zero for native) -void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { +void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { // This function is pretty complicated. It's main aim is to be efficient in speed and RAM // usage for the common case of positional only args. diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 79769e000e..94377238a0 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -182,6 +182,18 @@ endif ifeq ($(CIRCUITPY__EVE),1) SRC_PATTERNS += _eve/% endif +ifeq ($(CIRCUITPY_ESPCAMERA),1) +SRC_PATTERNS += espcamera/% +endif +ifeq ($(CIRCUITPY_ESPIDF),1) +SRC_PATTERNS += espidf/% +endif +ifeq ($(CIRCUITPY_ESPNOW),1) +SRC_PATTERNS += espnow/% +endif +ifeq ($(CIRCUITPY_ESPULP),1) +SRC_PATTERNS += espulp/% +endif ifeq ($(CIRCUITPY_FLOPPYIO),1) SRC_PATTERNS += floppyio/% endif diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index b4cbe83b95..5f140413bb 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -587,6 +587,18 @@ void supervisor_run_background_tasks_if_tick(void); #define MICROPY_WRAP_MP_EXECUTE_BYTECODE PLACE_IN_ITCM #endif +#ifndef MICROPY_WRAP_MP_LOAD_GLOBAL +#define MICROPY_WRAP_MP_LOAD_GLOBAL PLACE_IN_ITCM +#endif + +#ifndef MICROPY_WRAP_MP_LOAD_NAME +#define MICROPY_WRAP_MP_LOAD_NAME PLACE_IN_ITCM +#endif + +#ifndef MICROPY_WRAP_MP_OBJ_GET_TYPE +#define MICROPY_WRAP_MP_OBJ_GET_TYPE PLACE_IN_ITCM +#endif + #ifndef CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY #define CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY (0) #endif diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 046957751a..b8e2178870 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -560,6 +560,10 @@ CFLAGS += -DCIRCUITPY_TUSB_MEM_ALIGN=$(CIRCUITPY_TUSB_MEM_ALIGN) CIRCUITPY_TUSB_ATTR_USBRAM ?= ".bss.usbram" CFLAGS += -DCIRCUITPY_TUSB_ATTR_USBRAM=$(CIRCUITPY_TUSB_ATTR_USBRAM) +# Output function trace information from the ARM ITM. +CIRCUITPY_SWO_TRACE ?= 0 +CFLAGS += -DCIRCUITPY_SWO_TRACE=$(CIRCUITPY_SWO_TRACE) + # Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk # $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. # This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. diff --git a/py/gc.c b/py/gc.c index 0ced4c854d..1812507c61 100644 --- a/py/gc.c +++ b/py/gc.c @@ -231,7 +231,9 @@ bool gc_is_locked(void) { // children: mark the unmarked child blocks and put those newly marked // blocks on the stack. When all children have been checked, pop off the // topmost block on the stack and repeat with that one. -STATIC void gc_mark_subtree(size_t block) { +// We don't instrument these functions because they occur a lot during GC and +// fill up the output buffer quickly. +STATIC void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(size_t block) { // Start with the block passed in the argument. size_t sp = 0; for (;;) { @@ -350,7 +352,7 @@ STATIC void gc_sweep(void) { } // Mark can handle NULL pointers because it verifies the pointer is within the heap bounds. -STATIC void gc_mark(void *ptr) { +STATIC void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark)(void *ptr) { if (VERIFY_PTR(ptr)) { size_t block = BLOCK_FROM_PTR(ptr); if (ATB_GET_KIND(block) == AT_HEAD) { @@ -397,7 +399,7 @@ void gc_collect_ptr(void *ptr) { #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) __attribute__((no_sanitize_address)) #endif -static void *gc_get_ptr(void **ptrs, int i) { +static void *MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_get_ptr)(void **ptrs, int i) { #if MICROPY_DEBUG_VALGRIND if (!VALGRIND_CHECK_MEM_IS_ADDRESSABLE(&ptrs[i], sizeof(*ptrs))) { return NULL; diff --git a/py/mpconfig.h b/py/mpconfig.h index 9d68f4ce9d..d3842afbe7 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1827,6 +1827,17 @@ typedef double mp_float_t; #define MP_WEAK __attribute__((weak)) #endif +// Modifier for functions which should not be instrumented when tracing with +// -finstrument-functions +#ifndef MP_NO_INSTRUMENT +#define MP_NO_INSTRUMENT __attribute__((no_instrument_function)) +#endif + +// Modifier for functions which should ideally inlined +#ifndef MP_INLINE +#define MP_INLINE inline MP_NO_INSTRUMENT +#endif + // Modifier for functions which should be never inlined #ifndef MP_NOINLINE #define MP_NOINLINE __attribute__((noinline)) @@ -1847,6 +1858,12 @@ typedef double mp_float_t; #define MP_UNLIKELY(x) __builtin_expect((x), 0) #endif +// Modifier for functions which aren't often used. Calls will also be considered +// unlikely. Section names are `.text.unlikely` for use in linker scripts. +#ifndef MP_COLD +#define MP_COLD __attribute__((cold)) +#endif + // To annotate that code is unreachable #ifndef MP_UNREACHABLE #if defined(__GNUC__) diff --git a/py/obj.h b/py/obj.h index 86fbe5155f..92732b31dd 100644 --- a/py/obj.h +++ b/py/obj.h @@ -86,19 +86,19 @@ typedef struct _mp_obj_base_t mp_obj_base_t; #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1)) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 2; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 2)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 6; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) @@ -115,25 +115,25 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 1; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 2) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 2) | 1)) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 3; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 3)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 7) == 7; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) @@ -150,13 +150,13 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in); mp_obj_t mp_obj_new_float(mp_float_t value); #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((mp_int_t)(o)) & 1) != 0; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) @@ -166,17 +166,17 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) { #define mp_const_float_e MP_ROM_PTR((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000)) #define mp_const_float_pi MP_ROM_PTR((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000)) -static inline bool mp_obj_is_float(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; } -static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { +static MP_INLINE mp_float_t mp_obj_float_get(mp_const_obj_t o) { union { mp_float_t f; mp_uint_t u; } num = {.u = ((mp_uint_t)o - 0x80800000) & ~3}; return num.f; } -static inline mp_obj_t mp_obj_new_float(mp_float_t f) { +static MP_INLINE mp_obj_t mp_obj_new_float(mp_float_t f) { union { mp_float_t f; mp_uint_t u; @@ -185,37 +185,37 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 0xff80000f) == 0x00000006; } #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 4) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 4) | 0x00000006)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 0xff80000f) == 0x0000000e; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 4) #define MP_OBJ_NEW_IMMEDIATE_OBJ(val) ((mp_obj_t)(((val) << 4) | 0xe)) -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((mp_int_t)(o)) & 3) == 0; } #elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D -static inline bool mp_obj_is_small_int(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0001000000000000; } #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)((o) << 16)) >> 17) #define MP_OBJ_NEW_SMALL_INT(small_int) (((((uint64_t)(small_int)) & 0x7fffffffffff) << 1) | 0x0001000000000001) -static inline bool mp_obj_is_qstr(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_qstr(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0002000000000000; } #define MP_OBJ_QSTR_VALUE(o) ((((uint32_t)(o)) >> 1) & 0xffffffff) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)(((uint64_t)(((uint32_t)(qst)) << 1)) | 0x0002000000000001)) -static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0003000000000000; } #define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) ((((uint32_t)(o)) >> 46) & 3) @@ -230,17 +230,17 @@ static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #define mp_const_float_e {((mp_obj_t)((uint64_t)0x4005bf0a8b145769 + 0x8004000000000000))} #define mp_const_float_pi {((mp_obj_t)((uint64_t)0x400921fb54442d18 + 0x8004000000000000))} -static inline bool mp_obj_is_float(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return ((uint64_t)(o) & 0xfffc000000000000) != 0; } -static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { +static MP_INLINE mp_float_t mp_obj_float_get(mp_const_obj_t o) { union { mp_float_t f; uint64_t r; } num = {.r = o - 0x8004000000000000}; return num.f; } -static inline mp_obj_t mp_obj_new_float(mp_float_t f) { +static MP_INLINE mp_obj_t mp_obj_new_float(mp_float_t f) { union { mp_float_t f; uint64_t r; @@ -249,7 +249,7 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { } #endif -static inline bool mp_obj_is_obj(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_obj(mp_const_obj_t o) { return (((uint64_t)(o)) & 0xffff000000000000) == 0x0000000000000000; } #define MP_OBJ_TO_PTR(o) ((void *)(uintptr_t)(o)) @@ -454,7 +454,7 @@ typedef enum _mp_map_lookup_kind_t { MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND = 3, // only valid for mp_set_lookup } mp_map_lookup_kind_t; -static inline bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { +static MP_INLINE bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { assert(pos < map->alloc); return (map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL; } @@ -476,7 +476,7 @@ typedef struct _mp_set_t { mp_obj_t *table; } mp_set_t; -static inline bool mp_set_slot_is_filled(const mp_set_t *set, size_t pos) { +static MP_INLINE bool mp_set_slot_is_filled(const mp_set_t *set, size_t pos) { return (set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL; } @@ -821,7 +821,7 @@ extern const struct _mp_obj_exception_t mp_static_GeneratorExit_obj; #define mp_obj_is_tuple_compatible(o) (mp_type_get_getiter_slot(mp_obj_get_type(o)) == mp_obj_tuple_getiter) mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); -static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { +static MP_INLINE mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_const_false; } mp_obj_t mp_obj_new_cell(mp_obj_t obj); @@ -893,7 +893,7 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2); bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); // returns true if o is bool, small int or long int -static inline bool mp_obj_is_integer(mp_const_obj_t o) { +static MP_INLINE bool mp_obj_is_integer(mp_const_obj_t o) { return mp_obj_is_int(o) || mp_obj_is_bool(o); } @@ -940,7 +940,7 @@ mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in); void mp_init_emergency_exception_buf(void); -static inline mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { +static MP_INLINE mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { assert(exc_type->make_new == mp_obj_exception_make_new); return mp_obj_exception_make_new(exc_type, 1, 0, &arg); } @@ -957,42 +957,42 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t s #if MICROPY_PY_BUILTINS_FLOAT // float #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT -static inline float mp_obj_get_float_to_f(mp_obj_t o) { +static MP_INLINE float mp_obj_get_float_to_f(mp_obj_t o) { return mp_obj_get_float(o); } -static inline double mp_obj_get_float_to_d(mp_obj_t o) { +static MP_INLINE double mp_obj_get_float_to_d(mp_obj_t o) { return (double)mp_obj_get_float(o); } -static inline mp_obj_t mp_obj_new_float_from_f(float o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_f(float o) { return mp_obj_new_float(o); } -static inline mp_obj_t mp_obj_new_float_from_d(double o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_d(double o) { return mp_obj_new_float((mp_float_t)o); } #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE -static inline float mp_obj_get_float_to_f(mp_obj_t o) { +static MP_INLINE float mp_obj_get_float_to_f(mp_obj_t o) { return (float)mp_obj_get_float(o); } -static inline double mp_obj_get_float_to_d(mp_obj_t o) { +static MP_INLINE double mp_obj_get_float_to_d(mp_obj_t o) { return mp_obj_get_float(o); } -static inline mp_obj_t mp_obj_new_float_from_f(float o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_f(float o) { return mp_obj_new_float((mp_float_t)o); } -static inline mp_obj_t mp_obj_new_float_from_d(double o) { +static MP_INLINE mp_obj_t mp_obj_new_float_from_d(double o) { return mp_obj_new_float(o); } #endif #if MICROPY_FLOAT_HIGH_QUALITY_HASH mp_int_t mp_float_hash(mp_float_t val); #else -static inline mp_int_t mp_float_hash(mp_float_t val) { +static MP_INLINE mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; } #endif @@ -1031,7 +1031,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index); mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key); mp_obj_t mp_obj_dict_copy(mp_obj_t self_in); -static inline mp_map_t *mp_obj_dict_get_map(mp_obj_t dict) { +static MP_INLINE mp_map_t *mp_obj_dict_get_map(mp_obj_t dict) { return &((mp_obj_dict_t *)MP_OBJ_TO_PTR(dict))->map; } diff --git a/py/objdict.c b/py/objdict.c index 306205d12f..02aedacdd6 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -229,7 +229,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { /******************************************************************************/ /* dict methods */ -STATIC void mp_ensure_not_fixed(const mp_obj_dict_t *dict) { +STATIC void PLACE_IN_ITCM(mp_ensure_not_fixed)(const mp_obj_dict_t * dict) { if (dict->map.is_fixed) { mp_raise_TypeError(NULL); } @@ -643,7 +643,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in) { return self->map.used; } -mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { +mp_obj_t PLACE_IN_ITCM(mp_obj_dict_store)(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { mp_check_self(mp_obj_is_dict_or_ordereddict(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_ensure_not_fixed(self); diff --git a/py/objfun.c b/py/objfun.c index 55c3fbbb06..5a02869fcf 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -50,7 +50,7 @@ /******************************************************************************/ /* builtin functions */ -STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_0_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_0)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); @@ -68,7 +68,7 @@ const mp_obj_type_t mp_type_fun_builtin_0 = { ), }; -STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_1_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_1)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -85,7 +85,7 @@ const mp_obj_type_t mp_type_fun_builtin_1 = { ), }; -STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_2_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_2)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 2, 2, false); @@ -102,7 +102,7 @@ const mp_obj_type_t mp_type_fun_builtin_2 = { ), }; -STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_3_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_3)); mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); mp_arg_check_num(n_args, n_kw, 3, 3, false); @@ -119,7 +119,7 @@ const mp_obj_type_t mp_type_fun_builtin_3 = { ), }; -STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_builtin_var_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { assert(mp_obj_is_type(self_in, &mp_type_fun_builtin_var)); mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); @@ -418,7 +418,7 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byt #if MICROPY_EMIT_NATIVE -STATIC mp_obj_t fun_native_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_native_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { MP_STACK_CHECK(); mp_obj_fun_bc_t *self = self_in; mp_call_fun_t fun = MICROPY_MAKE_POINTER_CALLABLE((void *)self->bytecode); @@ -505,7 +505,7 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { } } -STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t PLACE_IN_ITCM(fun_asm_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_obj_fun_asm_t *self = self_in; mp_arg_check_num(n_args, n_kw, self->n_args, self->n_args, false); diff --git a/py/objproperty.c b/py/objproperty.c index e8ae5094fa..f55efc8bdb 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -99,7 +99,7 @@ const mp_obj_type_t mp_type_property = { extern const mp_obj_property_t __property_getter_start, __property_getter_end, __property_getset_start, __property_getset_end; #endif -const mp_obj_t *mp_obj_property_get(mp_obj_t self_in, size_t *n_proxy) { +const mp_obj_t *PLACE_IN_ITCM(mp_obj_property_get)(mp_obj_t self_in, size_t *n_proxy) { mp_check_self(mp_obj_is_type(self_in, &mp_type_property)); mp_obj_property_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_OPTIMIZE_PROPERTY_FLASH_SIZE diff --git a/py/pystack.c b/py/pystack.c index 43dfd4ed6c..696b033377 100644 --- a/py/pystack.c +++ b/py/pystack.c @@ -36,7 +36,7 @@ void mp_pystack_init(void *start, void *end) { MP_STATE_THREAD(pystack_cur) = start; } -void *mp_pystack_alloc(size_t n_bytes) { +void *PLACE_IN_ITCM(mp_pystack_alloc)(size_t n_bytes) { n_bytes = (n_bytes + (MICROPY_PYSTACK_ALIGN - 1)) & ~(MICROPY_PYSTACK_ALIGN - 1); #if MP_PYSTACK_DEBUG n_bytes += MICROPY_PYSTACK_ALIGN; diff --git a/py/pystack.h b/py/pystack.h index ed51e0c7e3..169d58b6f7 100644 --- a/py/pystack.h +++ b/py/pystack.h @@ -41,7 +41,7 @@ void *mp_pystack_alloc(size_t n_bytes); // This function can free multiple continuous blocks at once: just pass the // pointer to the block that was allocated first and it and all subsequently // allocated blocks will be freed. -static inline void mp_pystack_free(void *ptr) { +static MP_INLINE void mp_pystack_free(void *ptr) { assert((uint8_t *)ptr >= MP_STATE_THREAD(pystack_start)); assert((uint8_t *)ptr <= MP_STATE_THREAD(pystack_cur)); #if MP_PYSTACK_DEBUG @@ -59,16 +59,16 @@ static inline void mp_pystack_free(void *ptr) { MP_STATE_THREAD(pystack_cur) = (uint8_t *)ptr; } -static inline void mp_pystack_realloc(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_pystack_realloc(void *ptr, size_t n_bytes) { mp_pystack_free(ptr); mp_pystack_alloc(n_bytes); } -static inline size_t mp_pystack_usage(void) { +static MP_INLINE size_t mp_pystack_usage(void) { return MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start); } -static inline size_t mp_pystack_limit(void) { +static MP_INLINE size_t mp_pystack_limit(void) { return MP_STATE_THREAD(pystack_end) - MP_STATE_THREAD(pystack_start); } @@ -78,43 +78,43 @@ static inline size_t mp_pystack_limit(void) { #define mp_local_alloc(n_bytes) alloca(n_bytes) -static inline void mp_local_free(void *ptr) { +static MP_INLINE void mp_local_free(void *ptr) { (void)ptr; } -static inline void *mp_nonlocal_alloc(size_t n_bytes) { +static MP_INLINE void *mp_nonlocal_alloc(size_t n_bytes) { return m_new(uint8_t, n_bytes); } -static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { +static MP_INLINE void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { return m_renew(uint8_t, ptr, old_n_bytes, new_n_bytes); } -static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_nonlocal_free(void *ptr, size_t n_bytes) { m_del(uint8_t, ptr, n_bytes); } #else -static inline void *mp_local_alloc(size_t n_bytes) { +static MP_INLINE void *mp_local_alloc(size_t n_bytes) { return mp_pystack_alloc(n_bytes); } -static inline void mp_local_free(void *ptr) { +static MP_INLINE void mp_local_free(void *ptr) { mp_pystack_free(ptr); } -static inline void *mp_nonlocal_alloc(size_t n_bytes) { +static MP_INLINE void *mp_nonlocal_alloc(size_t n_bytes) { return mp_pystack_alloc(n_bytes); } -static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { +static MP_INLINE void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) { (void)old_n_bytes; mp_pystack_realloc(ptr, new_n_bytes); return ptr; } -static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) { +static MP_INLINE void mp_nonlocal_free(void *ptr, size_t n_bytes) { (void)n_bytes; mp_pystack_free(ptr); } diff --git a/py/qstr.c b/py/qstr.c index 083e12d6f0..96e2a79192 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -137,7 +137,7 @@ void qstr_init(void) { #endif } -STATIC const char *find_qstr(qstr q, qstr_attr_t *attr) { +STATIC const char *PLACE_IN_ITCM(find_qstr)(qstr q, qstr_attr_t *attr) { // search pool for this qstr // total_prev_len==0 in the final pool, so the loop will always terminate const qstr_pool_t *pool = MP_STATE_VM(last_pool); diff --git a/py/runtime.c b/py/runtime.c index 5d8be5672f..804b955e07 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1588,7 +1588,7 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i #endif // MICROPY_ENABLE_COMPILER -NORETURN void m_malloc_fail(size_t num_bytes) { +NORETURN MP_COLD void m_malloc_fail(size_t num_bytes) { DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes); #if MICROPY_ENABLE_GC if (gc_is_locked()) { @@ -1601,25 +1601,25 @@ NORETURN void m_malloc_fail(size_t num_bytes) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE -NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) { +NORETURN MP_COLD void mp_raise_type(const mp_obj_type_t *exc_type) { nlr_raise(mp_obj_new_exception(exc_type)); } -NORETURN void mp_raise_ValueError_no_msg(void) { +NORETURN MP_COLD void mp_raise_ValueError_no_msg(void) { mp_raise_type(&mp_type_ValueError); } -NORETURN void mp_raise_TypeError_no_msg(void) { +NORETURN MP_COLD void mp_raise_TypeError_no_msg(void) { mp_raise_type(&mp_type_TypeError); } -NORETURN void mp_raise_NotImplementedError_no_msg(void) { +NORETURN MP_COLD void mp_raise_NotImplementedError_no_msg(void) { mp_raise_type(&mp_type_NotImplementedError); } #else -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_string_t *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1627,19 +1627,19 @@ NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const compressed_strin } } -NORETURN void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list argptr) { +NORETURN MP_COLD void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, va_list argptr) { mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, argptr); nlr_raise(exception); } -NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(exc_type, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { +NORETURN MP_COLD void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1647,56 +1647,56 @@ NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { } } -NORETURN void mp_raise_AttributeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_AttributeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_AttributeError, msg); } -NORETURN void mp_raise_RuntimeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_RuntimeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_RuntimeError, msg); } -NORETURN void mp_raise_ImportError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ImportError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ImportError, msg); } -NORETURN void mp_raise_IndexError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_IndexError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_IndexError, msg); } -NORETURN void mp_raise_IndexError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_IndexError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_IndexError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_ValueError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ValueError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ValueError, msg); } -NORETURN void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_ValueError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_TypeError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_TypeError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_TypeError, msg); } -NORETURN void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_TypeError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_OSError_msg(const compressed_string_t *msg) { mp_raise_msg(&mp_type_OSError, msg); } -NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { +NORETURN MP_COLD void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(errno_), str, @@ -1704,26 +1704,26 @@ NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { nlr_raise(mp_obj_new_exception_args(&mp_type_OSError, 2, args)); } -NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_OSError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_ConnectionError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_ConnectionError, msg); } -NORETURN void mp_raise_BrokenPipeError(void) { +NORETURN MP_COLD void mp_raise_BrokenPipeError(void) { mp_raise_type_arg(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE)); } -NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg) { +NORETURN MP_COLD void mp_raise_NotImplementedError(const compressed_string_t *msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } -NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_NotImplementedError, fmt, argptr); @@ -1731,17 +1731,18 @@ NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, } -NORETURN void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { +NORETURN MP_COLD void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { va_list argptr; va_start(argptr,fmt); mp_raise_msg_vlist(&mp_type_OverflowError, fmt, argptr); va_end(argptr); } -NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { +NORETURN MP_COLD void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { nlr_raise(mp_obj_new_exception_arg1(exc_type, arg)); } +// Leave this as not COLD because it is used by iterators in normal execution. NORETURN void mp_raise_StopIteration(mp_obj_t arg) { if (arg == MP_OBJ_NULL) { mp_raise_type(&mp_type_StopIteration); @@ -1750,18 +1751,18 @@ NORETURN void mp_raise_StopIteration(mp_obj_t arg) { } } -NORETURN void mp_raise_OSError(int errno_) { +NORETURN MP_COLD void mp_raise_OSError(int errno_) { mp_raise_type_arg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)); } #endif #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK -NORETURN void mp_raise_recursion_depth(void) { +NORETURN MP_COLD void mp_raise_recursion_depth(void) { mp_raise_RuntimeError(MP_ERROR_TEXT("maximum recursion depth exceeded")); } #endif -NORETURN void mp_raise_ZeroDivisionError(void) { +NORETURN MP_COLD void mp_raise_ZeroDivisionError(void) { mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); } diff --git a/py/runtime.h b/py/runtime.h index 1a7a5d1698..d154772508 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -86,7 +86,7 @@ bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec); void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig); -static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { +static MP_INLINE void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { mp_arg_check_num_sig(n_args, n_kw, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, takes_kw)); } void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); @@ -115,16 +115,16 @@ mp_obj_t mp_arg_validate_type_or_none(mp_obj_t obj, const mp_obj_type_t *type, q mp_int_t mp_arg_validate_type_int(mp_obj_t obj, qstr arg_name); mp_obj_t mp_arg_validate_type_string(mp_obj_t obj, qstr arg_name); -static inline mp_obj_dict_t *PLACE_IN_ITCM(mp_locals_get)(void) { +static MP_INLINE mp_obj_dict_t *mp_locals_get(void) { return MP_STATE_THREAD(dict_locals); } -static inline void PLACE_IN_ITCM(mp_locals_set)(mp_obj_dict_t * d) { +static MP_INLINE void mp_locals_set(mp_obj_dict_t *d) { MP_STATE_THREAD(dict_locals) = d; } -static inline mp_obj_dict_t *PLACE_IN_ITCM(mp_globals_get)(void) { +static MP_INLINE mp_obj_dict_t *mp_globals_get(void) { return MP_STATE_THREAD(dict_globals); } -static inline void PLACE_IN_ITCM(mp_globals_set)(mp_obj_dict_t * d) { +static MP_INLINE void mp_globals_set(mp_obj_dict_t *d) { MP_STATE_THREAD(dict_globals) = d; } @@ -181,7 +181,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o); // may return MP_OBJ_STOP_ITERATIO mp_obj_t mp_iternext(mp_obj_t o); // will always return MP_OBJ_STOP_ITERATION instead of raising StopIteration(...) mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val); -static inline mp_obj_t mp_make_stop_iteration(mp_obj_t o) { +static MP_INLINE mp_obj_t mp_make_stop_iteration(mp_obj_t o) { MP_STATE_THREAD(stop_iteration_arg) = o; return MP_OBJ_STOP_ITERATION; } diff --git a/py/stackctrl.c b/py/stackctrl.c index d699d6da61..546987f04d 100644 --- a/py/stackctrl.c +++ b/py/stackctrl.c @@ -38,7 +38,7 @@ void mp_stack_set_top(void *top) { MP_STATE_THREAD(stack_top) = top; } -mp_uint_t mp_stack_usage(void) { +mp_uint_t PLACE_IN_ITCM(mp_stack_usage)(void) { // Assumes descending stack // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. __asm volatile (""); @@ -52,7 +52,7 @@ void mp_stack_set_limit(mp_uint_t limit) { MP_STATE_THREAD(stack_limit) = limit; } -void mp_stack_check(void) { +void PLACE_IN_ITCM(mp_stack_check)(void) { if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) { mp_raise_recursion_depth(); } diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index de4d66f9d8..c0195115fa 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -125,7 +125,7 @@ STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_ } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); -STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) { +STATIC inline void check_for_deinit(digitalio_digitalinout_obj_t *self) { if (common_hal_digitalio_digitalinout_deinited(self)) { raise_deinited_error(); } diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index 9e82654bc9..c4bd728f67 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -252,7 +252,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_enable_usb_drive), MP_ROM_PTR(&storage_enable_usb_drive_obj) }, //| class VfsFat: -//| def __init__(self, block_device: str) -> None: +//| def __init__(self, block_device: BlockDevice) -> None: //| """Create a new VfsFat filesystem around the given block device. //| //| :param block_device: Block device the the filesystem lives on""" @@ -267,7 +267,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = { //| ... //| //| @staticmethod -//| def mkfs(self) -> None: +//| def mkfs(block_device: BlockDevice) -> None: //| """Format the block device, deleting any data that may have been there. //| //| **Limitations**: On SAMD21 builds, `mkfs()` will raise ``OSError(22)`` when diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index db3d8d1e4d..ecdd914a8f 100644 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -197,7 +197,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_next_stack_limit_obj, superviso STATIC mp_obj_t supervisor_runtime_set_next_stack_limit(mp_obj_t self, mp_obj_t size_obj) { mp_int_t size = mp_obj_get_int(size_obj); mp_arg_validate_int_min(size, 256, MP_QSTR_size); - set_next_stack_size(size); + if (!set_next_stack_size(size)) { + mp_raise_msg_varg(&mp_type_AttributeError, + MP_ERROR_TEXT("can't set attribute '%q'"), + MP_QSTR_next_stack_limit); + } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_next_stack_limit_obj, supervisor_runtime_set_next_stack_limit); diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 08b4138202..922c2f0872 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include "shared/runtime/interrupt_char.h" #include "shared-bindings/bitmaptools/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Palette.h" @@ -376,6 +377,10 @@ void common_hal_bitmaptools_boundary_fill(displayio_bitmap_t *destination, } mp_obj_list_get(fill_area, &list_length, &fill_points); + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return; + } } // set dirty the area so displayio will draw diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index dc82d04e05..8cb80a661d 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -128,6 +128,9 @@ void displayio_bitmap_set_dirty_area(displayio_bitmap_t *self, const displayio_a } void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // Writes the color index value into a pixel position // Must update the dirty area separately @@ -160,6 +163,9 @@ void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // Copy region of "source" bitmap into "self" bitmap at location x,y in the "self" // If skip_value is encountered in the source bitmap, it will not be copied. // If skip_value is `None`, then all pixels are copied. @@ -213,6 +219,9 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 } void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } // update the dirty region displayio_area_t a = {x, y, x + 1, y + 1, NULL}; displayio_bitmap_set_dirty_area(self, &a); @@ -223,7 +232,7 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, } displayio_area_t *displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t *tail) { - if (self->dirty_area.x1 == self->dirty_area.x2) { + if (self->dirty_area.x1 == self->dirty_area.x2 || self->read_only) { return tail; } self->dirty_area.next = tail; @@ -231,11 +240,17 @@ displayio_area_t *displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, d } void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { + if (self->read_only) { + return; + } self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; } void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only")); + } displayio_area_t a = {0, 0, self->width, self->height, NULL}; displayio_bitmap_set_dirty_area(self, &a); diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c index 289fc47a68..74f828aea8 100644 --- a/shared-module/displayio/EPaperDisplay.c +++ b/shared-module/displayio/EPaperDisplay.c @@ -60,6 +60,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select, bool grayscale, bool acep, bool two_byte_sequence_length) { uint16_t color_depth = 1; + bool core_grayscale = true; if (highlight_color != 0x000000) { self->core.colorspace.tricolor = true; self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); @@ -70,9 +71,10 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t color_depth = 4; // bits. 7 colors + clean self->acep = acep; grayscale = false; + core_grayscale = false; } - displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, color_depth, grayscale, true, 1, true, true); + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, color_depth, core_grayscale, true, 1, true, true); self->set_column_window_command = set_column_window_command; self->set_row_window_command = set_row_window_command; @@ -340,7 +342,7 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t * memset(mask, 0, mask_length * sizeof(mask[0])); memset(buffer, 0, buffer_size * sizeof(buffer[0])); - if (self->grayscale) { + if (!self->acep) { self->core.colorspace.grayscale = true; self->core.colorspace.grayscale_bit = 7; } diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index a2ddc285fd..c61b9ebc82 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -81,7 +81,13 @@ void displayio_palette_get_color(displayio_palette_t *self, const _displayio_col } // Cache results when not dithering. - if (!self->dither && self->colors[palette_index].cached_colorspace == colorspace) { + _displayio_color_t *color = &self->colors[palette_index]; + // Check the grayscale settings because EPaperDisplay will change them on + // the same object. + if (!self->dither && + color->cached_colorspace == colorspace && + color->cached_colorspace_grayscale_bit == colorspace->grayscale_bit && + color->cached_colorspace_grayscale == colorspace->grayscale) { output_color->pixel = self->colors[palette_index].cached_color; return; } @@ -90,8 +96,10 @@ void displayio_palette_get_color(displayio_palette_t *self, const _displayio_col rgb888_pixel.pixel = self->colors[palette_index].rgb888; displayio_convert_color(colorspace, self->dither, &rgb888_pixel, output_color); if (!self->dither) { - self->colors[palette_index].cached_colorspace = colorspace; - self->colors[palette_index].cached_color = output_color->pixel; + color->cached_colorspace = colorspace; + color->cached_color = output_color->pixel; + color->cached_colorspace_grayscale = colorspace->grayscale; + color->cached_colorspace_grayscale_bit = colorspace->grayscale_bit; } } diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index e9b449c4e7..050423d052 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -51,6 +51,8 @@ typedef struct { uint32_t rgb888; const _displayio_colorspace_t *cached_colorspace; uint32_t cached_color; + uint8_t cached_colorspace_grayscale_bit; + bool cached_colorspace_grayscale; bool transparent; // This may have additional bits added later for blending. } _displayio_color_t; diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 7b6eec7e1b..060972d0c3 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -127,6 +127,7 @@ static bool usb_drive_set_enabled(bool enabled) { if (tud_connected()) { return false; } + filesystem_set_internal_writable_by_usb(enabled); storage_usb_is_enabled = enabled; return true; } diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index e87321ae79..11e122915c 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -129,14 +129,10 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size mp_raise_RuntimeError(translate("buffer too small")); } - size_t i; + size_t i = 0; byte *p_base = p; - for (i = 0; i < n_args;) { + while (*fmt) { mp_uint_t sz = 1; - if (*fmt == '\0') { - // more arguments given than used by format string; CPython raises struct.error here - mp_raise_RuntimeError(translate("too many arguments provided with the given format")); - } struct_validate_format(*fmt); if (unichar_isdigit(*fmt)) { @@ -144,14 +140,17 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size } if (*fmt == 's') { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ); - mp_uint_t to_copy = sz; - if (bufinfo.len < to_copy) { - to_copy = bufinfo.len; + if (i < n_args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i], &bufinfo, MP_BUFFER_READ); + mp_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); } - memcpy(p, bufinfo.buf, to_copy); - memset(p + to_copy, 0, sz - to_copy); + i++; p += sz; } else { while (sz--) { @@ -159,13 +158,16 @@ void shared_modules_struct_pack_into(mp_obj_t fmt_in, byte *p, byte *end_p, size if (*fmt == 'x') { mp_binary_set_val(fmt_type, *fmt, MP_OBJ_NEW_SMALL_INT(0), p_base, &p); } else { - mp_binary_set_val(fmt_type, *fmt, args[i], p_base, &p); + if (i < n_args) { + mp_binary_set_val(fmt_type, *fmt, args[i], p_base, &p); + } i++; } } } fmt++; } + (void)mp_arg_validate_length(n_args, i, MP_QSTR_values); } mp_obj_tuple_t *shared_modules_struct_unpack_from(mp_obj_t fmt_in, byte *p, byte *end_p, bool exact_size) { diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 35131faa4f..fab12c664e 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -278,7 +278,7 @@ void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self mp_arg_validate_length(tuple_len, 2, MP_QSTR_location); mp_int_t x = mp_arg_validate_type_int(tuple_items[0], MP_QSTR_x); - mp_int_t y = mp_arg_validate_type_int(tuple_items[0], MP_QSTR_y); + mp_int_t y = mp_arg_validate_type_int(tuple_items[1], MP_QSTR_y); bool dirty = false; if (self->x != x) { check_bounds_and_set_x(self, x); diff --git a/supervisor/linker.h b/supervisor/linker.h index 58068c1a4b..9666c4ca12 100644 --- a/supervisor/linker.h +++ b/supervisor/linker.h @@ -32,7 +32,8 @@ #if defined(IMXRT10XX) || defined(FOMU) || defined(STM32H7) || defined(RASPBERRYPI) #define PLACE_IN_DTCM_DATA(name) name __attribute__((section(".dtcm_data." #name))) #define PLACE_IN_DTCM_BSS(name) name __attribute__((section(".dtcm_bss." #name))) -#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name))) name +// Don't inline ITCM functions because that may pull them out of ITCM into other sections. +#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name),noinline,aligned(4))) name #else #define PLACE_IN_DTCM_DATA(name) name #define PLACE_IN_DTCM_BSS(name) name diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index db6d62f8e7..80f70b528a 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -42,7 +42,7 @@ STATIC volatile background_callback_t *volatile callback_head, *volatile callbac MP_WEAK void port_wake_main_task(void) { } -void background_callback_add_core(background_callback_t *cb) { +void PLACE_IN_ITCM(background_callback_add_core)(background_callback_t * cb) { CALLBACK_CRITICAL_BEGIN; if (cb->prev || callback_head == cb) { CALLBACK_CRITICAL_END; @@ -62,13 +62,13 @@ void background_callback_add_core(background_callback_t *cb) { port_wake_main_task(); } -void background_callback_add(background_callback_t *cb, background_callback_fun fun, void *data) { +void PLACE_IN_ITCM(background_callback_add)(background_callback_t * cb, background_callback_fun fun, void *data) { cb->fun = fun; cb->data = data; background_callback_add_core(cb); } -bool PLACE_IN_ITCM(background_callback_pending)(void) { +bool inline background_callback_pending(void) { return callback_head != NULL; } diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index 1eab59c384..345f55f2f1 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -33,6 +33,7 @@ #include "py/mpstate.h" #include "supervisor/flash.h" +#include "supervisor/linker.h" static mp_vfs_mount_t _mp_vfs; static fs_user_mount_t _internal_vfs; @@ -165,7 +166,7 @@ bool filesystem_init(bool create_allowed, bool force_create) { return true; } -void filesystem_flush(void) { +void PLACE_IN_ITCM(filesystem_flush)(void) { // Reset interval before next flush. filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; supervisor_flash_flush(); diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c index dfd7cf2050..53815c9836 100644 --- a/supervisor/shared/flash.c +++ b/supervisor/shared/flash.c @@ -132,7 +132,7 @@ static mp_uint_t flash_write_blocks(const uint8_t *src, uint32_t block_num, uint } } -void supervisor_flash_flush(void) { +void PLACE_IN_ITCM(supervisor_flash_flush)(void) { #if INTERNAL_FLASH_FILESYSTEM port_internal_flash_flush(); #else diff --git a/supervisor/shared/reload.c b/supervisor/shared/reload.c index 4e351704f8..da2ffc26e1 100644 --- a/supervisor/shared/reload.c +++ b/supervisor/shared/reload.c @@ -82,15 +82,19 @@ inline bool autoreload_is_enabled() { } void autoreload_trigger() { - if (autoreload_enabled & !autoreload_suspended) { - last_autoreload_trigger = supervisor_ticks_ms32(); - // Guard against the rare time that ticks is 0; - if (last_autoreload_trigger == 0) { - last_autoreload_trigger += 1; - } - // Initiate a reload of the VM immediately. Later code will pause to - // wait for the autoreload to become ready. Doing the VM exit - // immediately is clearer for the user. + if (!autoreload_enabled || autoreload_suspended != 0) { + return; + } + bool reload_initiated = autoreload_pending(); + last_autoreload_trigger = supervisor_ticks_ms32(); + // Guard against the rare time that ticks is 0; + if (last_autoreload_trigger == 0) { + last_autoreload_trigger += 1; + } + // Initiate a reload of the VM immediately. Later code will pause to + // wait for the autoreload to become ready. Doing the VM exit + // immediately is clearer for the user. + if (!reload_initiated) { reload_initiate(RUN_REASON_AUTO_RELOAD); } } @@ -111,5 +115,5 @@ bool autoreload_ready() { } bool autoreload_pending(void) { - return last_autoreload_trigger != 0; + return last_autoreload_trigger > 0; } diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 8709d3c356..0ab97fc9a9 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -34,6 +34,7 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" +#include "supervisor/linker.h" #include "supervisor/serial.h" #include "supervisor/shared/rgb_led_colors.h" #include "supervisor/shared/status_leds.h" @@ -121,12 +122,12 @@ safe_mode_t wait_for_safe_mode_reset(void) { return SAFE_MODE_NONE; } -void safe_mode_on_next_reset(safe_mode_t reason) { +void PLACE_IN_ITCM(safe_mode_on_next_reset)(safe_mode_t reason) { port_set_saved_word(SAFE_MODE_DATA_GUARD | (reason << 8)); } // Don't inline this so it's easy to break on it from GDB. -void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) { +void __attribute__((noinline,)) PLACE_IN_ITCM(reset_into_safe_mode)(safe_mode_t reason) { if (_safe_mode > SAFE_MODE_BROWNOUT && reason > SAFE_MODE_BROWNOUT) { while (true) { // This very bad because it means running in safe mode didn't save us. Only ignore brownout diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index be97cee234..148bb0bbd5 100644 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -35,7 +35,7 @@ extern uint32_t _estack; // Requested size. -static uint32_t next_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; +static uint32_t next_stack_size = 0; static uint32_t current_stack_size = 0; // Actual location and size, may be larger than requested. static uint32_t *stack_limit = NULL; @@ -49,11 +49,15 @@ static void allocate_stack(void) { stack_limit = port_stack_get_limit(); stack_length = (port_stack_get_top() - stack_limit) * sizeof(uint32_t); current_stack_size = stack_length; + next_stack_size = stack_length; } else { mp_uint_t regs[10]; mp_uint_t sp = cpu_get_regs_and_sp(regs); mp_uint_t c_size = (mp_uint_t)port_stack_get_top() - sp; + if (next_stack_size == 0) { + next_stack_size = CIRCUITPY_DEFAULT_STACK_SIZE; + } supervisor_allocation *stack_alloc = allocate_memory(c_size + next_stack_size + EXCEPTION_STACK_SIZE, true, false); if (stack_alloc == NULL) { stack_alloc = allocate_memory(c_size + CIRCUITPY_DEFAULT_STACK_SIZE + EXCEPTION_STACK_SIZE, true, false); @@ -103,8 +107,12 @@ size_t stack_get_length(void) { return stack_length; } -void set_next_stack_size(uint32_t size) { +bool set_next_stack_size(uint32_t size) { + if (port_has_fixed_stack()) { + return false; + } next_stack_size = size; + return true; } uint32_t get_next_stack_size(void) { diff --git a/supervisor/shared/stack.h b/supervisor/shared/stack.h index 4acda57354..4a03fcf275 100644 --- a/supervisor/shared/stack.h +++ b/supervisor/shared/stack.h @@ -37,7 +37,7 @@ void stack_resize(void); uint32_t *stack_get_bottom(void); size_t stack_get_length(void); // Next/current requested stack size. -void set_next_stack_size(uint32_t size); +bool set_next_stack_size(uint32_t size); uint32_t get_next_stack_size(void); uint32_t get_current_stack_size(void); bool stack_ok(void); diff --git a/supervisor/shared/status_bar.c b/supervisor/shared/status_bar.c index 4f5fa06464..16d23fe541 100644 --- a/supervisor/shared/status_bar.c +++ b/supervisor/shared/status_bar.c @@ -78,8 +78,8 @@ void supervisor_status_bar_update(void) { !shared_module_supervisor_status_bar_get_display(&shared_module_supervisor_status_bar_obj); // Suppress writes to console and/or display if status bar is not enabled for either or both. - bool prev_console_disable; - bool prev_display_disable; + bool prev_console_disable = false; + bool prev_display_disable = false; if (disable_console_writes) { prev_console_disable = serial_console_write_disable(true); diff --git a/supervisor/shared/translate/translate_impl.h b/supervisor/shared/translate/translate_impl.h index 1c144197cb..13da8c656b 100644 --- a/supervisor/shared/translate/translate_impl.h +++ b/supervisor/shared/translate/translate_impl.h @@ -48,7 +48,9 @@ inline #if !CIRCUITPY_LTO || CIRCUITPY_DEBUG < 1 __attribute__((always_inline)) #endif -const compressed_string_t *translate(const char *original) { +// Prevent instrumenting this because that disables the inlining we rely of for code size +// optimization. +__attribute__((no_instrument_function)) const compressed_string_t *translate(const char *original) { #ifndef NO_QSTR #define QDEF(id, hash, len, str) #define TRANSLATION(english_id, number) if (strcmp(original, english_id) == 0) { return &translation##number; } else diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 5ac8454312..1d600e1158 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -220,11 +220,11 @@ static void usb_background_do(void *unused) { usb_background(); } -void usb_background_schedule(void) { +void PLACE_IN_ITCM(usb_background_schedule)(void) { background_callback_add(&usb_callback, usb_background_do, NULL); } -void usb_irq_handler(int instance) { +void PLACE_IN_ITCM(usb_irq_handler)(int instance) { #if CFG_TUSB_MCU != OPT_MCU_RP2040 // For rp2040, IRQ handler is already installed and invoked automatically if (instance == CIRCUITPY_USB_DEVICE_INSTANCE) { diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 97530b970b..2caacbd39b 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -49,6 +49,7 @@ #include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/Hash.h" +#include "lib/oofatfs/diskio.h" #if CIRCUITPY_MDNS #include "shared-bindings/mdns/RemoteService.h" @@ -804,7 +805,7 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _update_encoded_ip(); // Note: this leverages the fact that C concats consecutive string literals together. mp_printf(&_socket_print, - "{\"web_api_version\": 1, " + "{\"web_api_version\": 2, " "\"version\": \"" MICROPY_GIT_TAG "\", " "\"build_date\": \"" MICROPY_BUILD_DATE "\", " "\"board_name\": \"" MICROPY_HW_BOARD_NAME "\", " @@ -828,6 +829,32 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * _send_chunk(socket, ""); } +static void _reply_with_diskinfo_json(socketpool_socket_obj_t *socket, _request *request) { + _send_str(socket, OK_JSON); + _cors_header(socket, request); + _send_str(socket, "\r\n"); + mp_print_t _socket_print = {socket, _print_chunk}; + + DWORD free_clusters; + FATFS *fs = filesystem_circuitpy(); + FRESULT blk_result = f_getfree(fs, &free_clusters); + uint16_t block_size; + if (blk_result == FR_OK) { + disk_ioctl(fs, GET_SECTOR_SIZE, &block_size); + } + + uint16_t total_size = fs->n_fatent - 2; + + mp_printf(&_socket_print, + "{\"free\": %d, " + "\"block_size\": %d, " + "\"total\": %d}", free_clusters * block_size, block_size, total_size * block_size); + + // Empty chunk signals the end of the response. + _send_chunk(socket, ""); +} + + // FATFS has a two second timestamp resolution but the BLE API allows for nanosecond resolution. // This function truncates the time the time to a resolution storable by FATFS and fills in the // FATFS encoded version into fattime. @@ -1228,6 +1255,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) { _reply_with_devices_json(socket, request); } else if (strcmp(path, "/version.json") == 0) { _reply_with_version_json(socket, request); + } else if (strcmp(path, "/diskinfo.json") == 0) { + _reply_with_diskinfo_json(socket, request); } else if (strcmp(path, "/serial/") == 0) { if (!request->authenticated) { if (_api_password[0] != '\0') { diff --git a/supervisor/stub/stack.c b/supervisor/stub/stack.c index 2abc197878..bb6e0d4cb0 100644 --- a/supervisor/stub/stack.c +++ b/supervisor/stub/stack.c @@ -39,8 +39,9 @@ void stack_init(void) { void stack_resize(void) { } -void set_next_stack_size(uint32_t size) { +bool set_next_stack_size(uint32_t size) { (void)size; + return true; } uint32_t get_current_stack_size(void) { diff --git a/tests/circuitpython/struct_nargs.py b/tests/circuitpython/struct_nargs.py new file mode 100644 index 0000000000..0a0cb140c3 --- /dev/null +++ b/tests/circuitpython/struct_nargs.py @@ -0,0 +1,38 @@ +import struct + + +def do_pack(*args): + try: + print(struct.pack(*args)) + except Exception as e: + print("ERROR") + + +do_pack("H") +do_pack("H", 1) +do_pack("H", 1, 2) + +do_pack("2H") +do_pack("2H", 1) +do_pack("2H", 1, 2) + +do_pack("3H") +do_pack("3H", 1) +do_pack("3H", 1, 2) +do_pack("3H", 1, 2, 3) +do_pack("3H", 1, 2, 3, 4) + +do_pack("4sH", b"x") +do_pack("4sH", b"x", 1) +do_pack("4sH", b"x", 1, 2) + +do_pack("4s2H", b"x") +do_pack("4s2H", b"x", 1) +do_pack("4s2H", b"x", 1, 2) +do_pack("4s2H", b"x", 1, 2, 3) + +do_pack("4s3H", b"x") +do_pack("4s3H", b"x", 1) +do_pack("4s3H", b"x", 1, 2) +do_pack("4s3H", b"x", 1, 2, 3) +do_pack("4s3H", b"x", 1, 2, 3, 4) diff --git a/tests/perf_bench/benchrun.py b/tests/perf_bench/benchrun.py index 90c303dd29..87b6489d07 100644 --- a/tests/perf_bench/benchrun.py +++ b/tests/perf_bench/benchrun.py @@ -4,7 +4,7 @@ def bm_run(N, M): except ImportError: import time - ticks_us = lambda: int(time.perf_counter() * 1000000) + ticks_us = lambda: int(time.monotonic_ns() // 1000) ticks_diff = lambda a, b: a - b # Pick sensible parameters given N, M diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index 5f299281fd..3d3639e057 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -7,8 +7,12 @@ import os import subprocess import sys +import time import argparse from glob import glob +from rich.live import Live +from rich.console import Console +from rich.table import Table sys.path.append("../tools") import pyboard @@ -37,7 +41,7 @@ def compute_stats(lst): return avg, var**0.5 -def run_script_on_target(target, script): +def run_script_on_target(target, script, run_command=None): output = b"" err = None @@ -45,50 +49,72 @@ def run_script_on_target(target, script): # Run via pyboard interface try: target.enter_raw_repl() + start_ts = time.monotonic_ns() output = target.exec_(script) + if run_command: + start_ts = time.monotonic_ns() + output = target.exec_(run_command) + end_ts = time.monotonic_ns() except pyboard.PyboardError as er: + end_ts = time.monotonic_ns() err = er + finally: + target.exit_raw_repl() else: # Run local executable try: + if run_command: + script += run_command + start_ts = time.monotonic_ns() p = subprocess.run( target, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, input=script ) + end_ts = time.monotonic_ns() output = p.stdout except subprocess.CalledProcessError as er: + end_ts = time.monotonic_ns() err = er - return str(output.strip(), "ascii"), err + return str(output.strip(), "ascii"), err, (end_ts - start_ts) // 1000 def run_feature_test(target, test): with open("feature_check/" + test + ".py", "rb") as f: script = f.read() - output, err = run_script_on_target(target, script) + output, err, _ = run_script_on_target(target, script) if err is None: return output else: return "CRASH: %r" % err -def run_benchmark_on_target(target, script): - output, err = run_script_on_target(target, script) +def run_benchmark_on_target(target, script, run_command=None): + output, err, runtime_us = run_script_on_target(target, script, run_command) if err is None: time, norm, result = output.split(None, 2) try: - return int(time), int(norm), result + return int(time), int(norm), result, runtime_us except ValueError: - return -1, -1, "CRASH: %r" % output + return -1, -1, "CRASH: %r" % output, runtime_us else: - return -1, -1, "CRASH: %r" % err + return -1, -1, "CRASH: %r" % err, runtime_us -def run_benchmarks(target, param_n, param_m, n_average, test_list): +def run_benchmarks(console, target, param_n, param_m, n_average, test_list): skip_complex = run_feature_test(target, "complex") != "complex" skip_native = run_feature_test(target, "native_check") != "native" + table = Table(show_header=True) + table.add_column("Test") + table.add_column("Time", justify="right") + table.add_column("Score", justify="right") + table.add_column("Ref Time", justify="right") + + live = Live(table, console=console) + live.start() + for test_file in sorted(test_list): - print(test_file + ": ", end="") + # print(test_file + ": ", end="") # Check if test should be skipped skip = ( @@ -99,6 +125,7 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): ) if skip: print("skip") + table.add_row(test_file, *(["skip"] * 6)) continue # Create test script @@ -106,7 +133,7 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): test_script = f.read() with open(BENCH_SCRIPT_DIR + "benchrun.py", "rb") as f: test_script += f.read() - test_script += b"bm_run(%u, %u)\n" % (param_n, param_m) + bm_run = b"bm_run(%u, %u)\n" % (param_n, param_m) # Write full test script if needed if 0: @@ -115,12 +142,15 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): # Run MicroPython a given number of times times = [] + runtimes = [] scores = [] error = None result_out = None for _ in range(n_average): - time, norm, result = run_benchmark_on_target(target, test_script) - if time < 0 or norm < 0: + self_time, norm, result, runtime_us = run_benchmark_on_target( + target, test_script, bm_run + ) + if self_time < 0 or norm < 0: error = result break if result_out is None: @@ -128,30 +158,43 @@ def run_benchmarks(target, param_n, param_m, n_average, test_list): elif result != result_out: error = "FAIL self" break - times.append(time) - scores.append(1e6 * norm / time) + times.append(self_time) + runtimes.append(runtime_us) + scores.append(1e6 * norm / self_time) # Check result against truth if needed if error is None and result_out != "None": - _, _, result_exp = run_benchmark_on_target(PYTHON_TRUTH, test_script) + _, _, result_exp, _ = run_benchmark_on_target(PYTHON_TRUTH, test_script, bm_run) if result_out != result_exp: error = "FAIL truth" if error is not None: - print(error) + print(test_file, error) + if error == "no matching params": + table.add_row(test_file, *([None] * 3)) + else: + table.add_row(test_file, *(["error"] * 3)) else: t_avg, t_sd = compute_stats(times) + r_avg, r_sd = compute_stats(runtimes) s_avg, s_sd = compute_stats(scores) - print( - "{:.2f} {:.4f} {:.2f} {:.4f}".format( - t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg - ) + # print( + # "{:.2f} {:.4f} {:.2f} {:.4f} {:.2f} {:.4f}".format( + # t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg, r_avg, 100 * r_sd / r_avg + # ) + # ) + table.add_row( + test_file, + f"{t_avg:.2f}±{100 * t_sd / t_avg:.1f}%", + f"{s_avg:.2f}±{100 * s_sd / s_avg:.1f}%", + f"{r_avg:.2f}±{100 * r_sd / r_avg:.1f}%", ) if 0: print(" times: ", times) print(" scores:", scores) - sys.stdout.flush() + live.update(table, refresh=True) + live.stop() def parse_output(filename): @@ -268,9 +311,10 @@ def main(): else: tests = sorted(args.files) + console = Console() print("N={} M={} n_average={}".format(N, M, n_average)) - run_benchmarks(target, N, M, n_average, tests) + run_benchmarks(console, target, N, M, n_average, tests) if isinstance(target, pyboard.Pyboard): target.exit_raw_repl() diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 65f67f0727..8014dd3010 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -35,15 +35,15 @@ bitmaptools btree cexample cmath collections cppexample displayio errno ffi framebuf gc hashlib json math qrio rainbowio -re sys termios traceback -ubinascii uctypes uerrno uheapq -uio ujson ulab ulab.numpy -ulab.numpy.fft ulab.numpy.linalg ulab.scipy -ulab.scipy.linalg ulab.scipy.optimize -ulab.scipy.signal ulab.scipy.special -ulab.utils uos urandom ure -uselect ustruct utime utimeq -uzlib zlib +re struct sys termios +traceback ubinascii uctypes uerrno +uheapq uio ujson ulab +ulab.numpy ulab.numpy.fft ulab.numpy.linalg +ulab.scipy ulab.scipy.linalg +ulab.scipy.optimize ulab.scipy.signal +ulab.scipy.special ulab.utils uos +urandom ure uselect utime +utimeq uzlib zlib ime utime utimeq diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py index fa53c81829..f549b6f6f1 100755 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -82,10 +82,12 @@ def git_diff(pattern: str): ) +compute_diff = bool(os.environ.get("BASE_SHA") and os.environ.get("HEAD_SHA")) + if len(sys.argv) > 1: print("Using files list on commandline") changed_files = set(sys.argv[1:]) -elif os.environ.get("BASE_SHA") and os.environ.get("HEAD_SHA"): +elif compute_diff: print("Using files list by computing diff") changed_files = git_diff("$BASE_SHA...$HEAD_SHA") if os.environ.get("GITHUB_EVENT_NAME") == "pull_request": @@ -117,25 +119,23 @@ def set_output(name: str, value): def set_boards(build_all: bool): - # Get boards in json format - boards_info_json = build_board_info.get_board_mapping() all_board_ids = set() - port_to_boards = {} + boards_to_build = all_board_ids if build_all else set() + board_to_port = {} - board_settings = {} - for board_id in boards_info_json: - info = boards_info_json[board_id] - if info.get("alias", False): + port_to_board = {} + board_setting = {} + + for id, info in build_board_info.get_board_mapping().items(): + if info.get("alias"): continue - all_board_ids.add(board_id) port = info["port"] - if port not in port_to_boards: - port_to_boards[port] = set() - port_to_boards[port].add(board_id) - board_to_port[board_id] = port + all_board_ids.add(id) + board_to_port[id] = port + port_to_board.setdefault(port, set()).add(id) def compute_board_settings(boards): - need = set(boards) - set(board_settings.keys()) + need = set(boards) - set(board_setting.keys()) if not need: return @@ -146,78 +146,76 @@ def set_boards(build_all: bool): ) with ThreadPoolExecutor(max_workers=os.cpu_count()) as ex: - board_settings.update(ex.map(get_settings, need)) - - boards_to_build = all_board_ids + board_setting.update(ex.map(get_settings, need)) if not build_all: - boards_to_build = set() - board_pattern = re.compile(r"^ports/[^/]+/boards/([^/]+)/") - port_pattern = re.compile(r"^ports/([^/]+)/") - module_pattern = re.compile( + pattern_port = re.compile(r"^ports/([^/]+)/") + pattern_board = re.compile(r"^ports/[^/]+/boards/([^/]+)/") + pattern_module = re.compile( r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/" ) - for p in changed_files: + + for file in changed_files: + if len(all_board_ids) == len(boards_to_build): + break + + if any([file.startswith(path) for path in IGNORE_BOARD]): + continue + # See if it is board specific - board_matches = board_pattern.search(p) + board_matches = pattern_board.search(file) if board_matches: - board = board_matches.group(1) - boards_to_build.add(board) + boards_to_build.add(board_matches.group(1)) continue # See if it is port specific - port_matches = port_pattern.search(p) + port_matches = pattern_port.search(file) + module_matches = pattern_module.search(file) port = port_matches.group(1) if port_matches else None - module_matches = module_pattern.search(p) if port and not module_matches: if port != "unix": - boards_to_build.update(port_to_boards[port]) - continue - - if any([p.startswith(d) for d in IGNORE_BOARD]): + boards_to_build.update(port_to_board[port]) continue # As a (nearly) last resort, for some certain files, we compute the settings from the - # makefile for each board and determine whether to build them that way. - if p.startswith("frozen") or p.startswith("supervisor") or module_matches: - if port: - board_ids = port_to_boards[port] - else: - board_ids = all_board_ids - compute_board_settings(board_ids) - for board in board_ids: - settings = board_settings[board] + # makefile for each board and determine whether to build them that way + if file.startswith("frozen") or file.startswith("supervisor") or module_matches: + boards = port_to_board[port] if port else all_board_ids + compute_board_settings(boards) - # Check frozen files to see if they are in each board. - frozen = settings.get("FROZEN_MPY_DIRS", "") - if frozen and p.startswith("frozen") and p in frozen: - boards_to_build.add(board) - continue + for board in boards: + settings = board_setting[board] - # Check supervisor files. This is useful for limiting workflow changes to the - # relevant boards. - supervisor = settings["SRC_SUPERVISOR"] - if p.startswith("supervisor"): - if p in supervisor: + # Check frozen files to see if they are in each board + if file.startswith("frozen"): + if file in settings.get("FROZEN_MPY_DIRS", ""): boards_to_build.add(board) continue - web_workflow = settings["CIRCUITPY_WEB_WORKFLOW"] - while web_workflow.startswith("$("): - web_workflow = settings[web_workflow[2:-1]] - if ( - p.startswith("supervisor/shared/web_workflow/static/") - and web_workflow != "0" - ): + # Check supervisor files + # This is useful for limiting workflow changes to the relevant boards + if file.startswith("supervisor"): + if file in settings["SRC_SUPERVISOR"]: boards_to_build.add(board) continue + if file.startswith("supervisor/shared/web_workflow/static/"): + web_workflow = settings["CIRCUITPY_WEB_WORKFLOW"] + + while web_workflow.startswith("$("): + web_workflow = settings[web_workflow[2:-1]] + + if web_workflow != "0": + boards_to_build.add(board) + continue + # Check module matches if module_matches: module = module_matches.group(2) + "/" if module in settings["SRC_PATTERNS"]: boards_to_build.add(board) continue + continue # Otherwise build it all @@ -225,7 +223,7 @@ def set_boards(build_all: bool): break # Append previously failed boards - boards_to_build.update(last_failed_jobs.get("ports") or []) + boards_to_build.update(last_failed_jobs.get("ports", [])) print("Building boards:", bool(boards_to_build)) @@ -249,16 +247,16 @@ def set_boards(build_all: bool): set_output("ports", json.dumps(port_to_boards_to_build)) -def set_docs(build_doc: bool): - if not build_doc: +def set_docs(run: bool): + if not run: if last_failed_jobs.get("docs"): - build_doc = True + run = True else: - doc_pattern = re.compile(PATTERN_DOCS) + pattern_doc = re.compile(PATTERN_DOCS) github_workspace = os.environ.get("GITHUB_WORKSPACE") or "" github_workspace = github_workspace and github_workspace + "/" for file in changed_files: - if doc_pattern.search(file) and ( + if pattern_doc.search(file) and ( ( subprocess.run( f"git diff -U0 $BASE_SHA...$HEAD_SHA {github_workspace + file} | grep -o -m 1 '^[+-]\/\/|'", @@ -269,44 +267,42 @@ def set_docs(build_doc: bool): if file.endswith(".c") else True ): - build_doc = True + run = True break # Set the step outputs - print("Building docs:", build_doc) - set_output("docs", build_doc) + print("Building docs:", run) + set_output("docs", run) -def set_windows(build_windows: bool): - if not build_windows: +def set_windows(run: bool): + if not run: if last_failed_jobs.get("windows"): - build_windows = True + run = True else: for file in changed_files: for pattern in PATTERN_WINDOWS: if file.startswith(pattern) and not any( - [file.startswith(d) for d in IGNORE_BOARD] + [file.startswith(path) for path in IGNORE_BOARD] ): - build_windows = True + run = True break else: continue break # Set the step outputs - print("Building windows:", build_windows) - set_output("windows", build_windows) + print("Building windows:", run) + set_output("windows", run) def main(): - # Build all if no changed files - build_all = not changed_files - print("Running: " + ("all" if build_all else "conditionally")) - + run_all = not changed_files and not compute_diff + print("Running: " + ("all" if run_all else "conditionally")) # Set jobs - set_docs(build_all) - set_windows(build_all) - set_boards(build_all) + set_docs(run_all) + set_windows(run_all) + set_boards(run_all) if __name__ == "__main__": diff --git a/tools/cortex-m-fault-gdb.py b/tools/cortex-m-fault-gdb.py new file mode 100644 index 0000000000..31b76aa1d4 --- /dev/null +++ b/tools/cortex-m-fault-gdb.py @@ -0,0 +1,106 @@ +"""Source this file into gdb `source ../../tools/cortex-m-fault-gdb.py` then run + `cortex-m-fault` to print basic info about the fault registers.""" + +SCS = 0xE000E000 +SCB = SCS + 0x0D00 +CPUID = SCB + 0x000 # (R/ ) CPUID Base Register */ +ICSR = SCB + 0x004 # (R/W) Interrupt Control and State Register */ +VTOR = SCB + 0x008 # (R/W) Vector Table Offset Register */ +AIRCR = SCB + 0x00C # (R/W) Application Interrupt and Reset Control Register */ +SCR = SCB + 0x010 # (R/W) System Control Register */ +CCR = SCB + 0x014 # (R/W) Configuration Control Register */ +SHCSR = SCB + 0x024 # (R/W) System Handler Control and State Register */ +CFSR = SCB + 0x028 # (R/W) Configurable Fault Status Register */ +HFSR = SCB + 0x02C # (R/W) HardFault Status Register */ +DFSR = SCB + 0x030 # (R/W) Debug Fault Status Register */ +MMFAR = SCB + 0x034 # (R/W) MemManage Fault Address Register */ +BFAR = SCB + 0x038 # (R/W) BusFault Address Register */ +AFSR = SCB + 0x03C # (R/W) Auxiliary Fault Status Register */ + +PARTS = {0xC27: "Cortex M7"} + +EXCEPTIONS = { + 0: "Thread mode", + 2: "Non Maskable Interrupt", + 3: "Hard Fault", + 4: "MemManage Fault", + 5: "Bus Fault", + 6: "Usage Fault", + 11: "SVCAll", + 14: "PendSV", + 15: "SysTick", +} + + +class CortexMFault(gdb.Command): + def __init__(self): + super(CortexMFault, self).__init__("cortex-m-fault", gdb.COMMAND_USER) + + def _read(self, address): + i = gdb.selected_inferior() + return i.read_memory(address, 4).cast("I")[0] + + def invoke(self, arg, from_tty): + cpuid = self._read(CPUID) + implementer = cpuid >> 24 + if implementer != 0x41: + raise RuntimeError() + variant = (cpuid >> 20) & 0xF + constant = (cpuid >> 16) & 0xF + if constant != 0xF: + raise RuntimeError() + revision = cpuid & 0xF + part_no = (cpuid >> 4) & 0xFFF + print(PARTS[part_no]) + icsr = self._read(ICSR) + if (icsr & (1 << 11)) != 0: + print("No preempted exceptions") + else: + print("Another exception was preempted") + vectactive = icsr & 0x1FF + if vectactive != 0: + if vectactive in EXCEPTIONS: + print(EXCEPTIONS[vectactive]) + else: + print(vectactive - 16) + + vtor = self._read(VTOR) + # print(hex(self._read(SHCSR))) + cfsr = self._read(CFSR) + ufsr = cfsr >> 16 + bfsr = (cfsr >> 8) & 0xFF + mmfsr = cfsr & 0xFF + print("ufsr", hex(ufsr), "bfsr", hex(bfsr), "mmfsr", hex(mmfsr)) + if (bfsr & (1 << 7)) != 0: + print("Bad address", hex(self._read(BFAR))) + if (bfsr & (1 << 3)) != 0: + print("Unstacking from exception error") + if (bfsr & (1 << 2)) != 0: + print("Imprecise data bus error") + if (bfsr & (1 << 1)) != 0: + print("Precise data bus error") + if (bfsr & (1 << 0)) != 0: + print("Instruction bus error") + + if (mmfsr & (1 << 7)) != 0: + print("Bad address", hex(self._read(MMFAR))) + if (mmfsr & (1 << 3)) != 0: + print("Unstacking from exception error") + if (mmfsr & (1 << 1)) != 0: + print("Data access violation") + if (mmfsr & (1 << 0)) != 0: + print("Instruction access violation") + + if (ufsr & (1 << 8)) != 0: + print("Unaligned access") + if (ufsr & (1 << 0)) != 0: + print("Undefined instruction") + hfsr = self._read(HFSR) + if (hfsr & (1 << 30)) != 0: + print("Forced hard fault") + if (hfsr & (1 << 1)) != 0: + print("Bus fault when reading vector table") + print("VTOR", hex(vtor)) + + +CortexMFault() diff --git a/tools/cpboard.py b/tools/cpboard.py index 46ae659d34..12d7d374a3 100644 --- a/tools/cpboard.py +++ b/tools/cpboard.py @@ -9,6 +9,7 @@ # SPDX-License-Identifier: MIT import os +import pathlib import re import serial import sys @@ -80,6 +81,7 @@ class REPL: else: timeout_count += 1 if timeout is not None and timeout_count >= 100 * timeout: + print("timeout") raise TimeoutError(110, "timeout waiting for", ending) time.sleep(0.01) return data @@ -93,16 +95,18 @@ class REPL: for i in range(0, len(data), chunk_size): chunk = data[i : min(i + chunk_size, len(data))] self.session += chunk - self.serial.write(chunk) + c = self.serial.write(chunk) + if c < len(chunk): + raise RuntimeError() time.sleep(0.01) def reset(self): # Use read() since serial.reset_input_buffer() fails with termios.error now and then self.read() self.session = b"" - self.write(b"\r" + REPL.CHAR_CTRL_C + REPL.CHAR_CTRL_C) # interrupt any running program + self.write(REPL.CHAR_CTRL_C + REPL.CHAR_CTRL_C) # interrupt any running program self.write(b"\r" + REPL.CHAR_CTRL_B) # enter or reset friendly repl - data = self.read_until(b">>> ") + self.read_until(b">>> ", timeout=60) def execute(self, code, timeout=10, wait_for_response=True): self.read() # Throw away @@ -161,7 +165,10 @@ class Disk: self._path = mount[0][1] else: name = os.path.basename(dev) - sh.pmount("-tvfat", dev, name, _timeout=10) + try: + sh.pmount("-tvfat", dev, name, _timeout=10) + except sh.CommandNotFound: + raise ValueError() self.mountpoint = "/media/" + name self._path = self.mountpoint @@ -347,7 +354,7 @@ class CPboard: return cls(dev, baudrate=baudrate, wait=wait, timeout=timeout) def __init__(self, device, baudrate=115200, wait=0, timeout=10): - self.device = device + self.device = str(pathlib.Path(device).resolve()) self.usb_dev = None try: # Is it a usb.core.Device? @@ -370,6 +377,10 @@ class CPboard: self.bootloader = False self.repl = REPL(self) + # Disable autoreload so that file copies won't mess us up. + with self: + self.exec("import supervisor;supervisor.runtime.autoreload = False") + def __enter__(self): self.open() return self @@ -507,9 +518,12 @@ class CPboard: part = [part for part in disks if "part1" in part] if not part: - raise RuntimeError("Disk not found for: " + self.device) + return None - return Disk(part[0]) + try: + return Disk(part[0]) + except ValueError: + return None @property def firmware(self): @@ -548,18 +562,33 @@ PyboardError = CPboardError class Pyboard: def __init__(self, device, baudrate=115200, user="micro", password="python", wait=0): self.board = CPboard.from_try_all(device, baudrate=baudrate, wait=wait) - with self.board.disk as disk: - disk.copy("skip_if.py") + disk = self.board.disk + if disk: + with disk as open_disk: + open_disk.copy("skip_if.py") def close(self): self.board.close() def enter_raw_repl(self): self.board.open() + self.board.repl.reset() + + def exit_raw_repl(self): + self.close() def execfile(self, filename): return self.board.execfile(filename) + def exec_(self, command, data_consumer=None): + try: + output, error = self.board.repl.execute(command, timeout=20000, wait_for_response=True) + except OSError as e: + raise CPboardError("timeout", e) + if error: + raise CPboardError("exception", output, error) + return output + def eval_namedtuple(board, command): from collections import namedtuple diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index 7165db84cc..350988bab0 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -121,7 +121,7 @@ if tile_y == 16: blinka_size = 16 c_file.write( """\ -uint32_t blinka_bitmap_data[32] = { +const uint32_t blinka_bitmap_data[32] = { 0x00000011, 0x11000000, 0x00000111, 0x53100000, 0x00000111, 0x56110000, @@ -145,7 +145,7 @@ else: blinka_size = 12 c_file.write( """\ -uint32_t blinka_bitmap_data[28] = { +const uint32_t blinka_bitmap_data[28] = { 0x00000111, 0x00000000, 0x00001153, 0x10000000, 0x00001156, 0x11000000, @@ -164,11 +164,11 @@ uint32_t blinka_bitmap_data[28] = { c_file.write( """\ -displayio_bitmap_t blinka_bitmap = {{ +const displayio_bitmap_t blinka_bitmap = {{ .base = {{.type = &displayio_bitmap_type }}, .width = {0}, .height = {0}, - .data = blinka_bitmap_data, + .data = (uint32_t*) blinka_bitmap_data, .stride = 2, .bits_per_value = 4, .x_shift = 3, @@ -211,7 +211,7 @@ displayio_palette_t blinka_palette = {{ displayio_tilegrid_t supervisor_blinka_sprite = {{ .base = {{.type = &displayio_tilegrid_type }}, - .bitmap = &blinka_bitmap, + .bitmap = (displayio_bitmap_t*) &blinka_bitmap, .pixel_shader = &blinka_palette, .x = 0, .y = 0, diff --git a/tools/swo_function_trace.py b/tools/swo_function_trace.py new file mode 100644 index 0000000000..bdc1b0f840 --- /dev/null +++ b/tools/swo_function_trace.py @@ -0,0 +1,143 @@ +"""This prints out Chrome Trace Formatted json that can be viewed in Perfetto or Spall. +https://ui.perfetto.dev/ +https://gravitymoth.com/spall/spall.html + +Format: +https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview# + +Connect a USB to Serial converter to the SWO pin and then provide the serial +device to this script. It should be 1MBaud SWO signal. CTRL-C when you've captured enough data and +then it'll process and output. + +pip install pysigrok-libsigrokdecode +python tools/swo_function_trace.py /dev/ttyACM0 build-metro_m7_1011/firmware.elf > trace.json +""" + +import serial +import sys +import sigrokdecode +import time +import json + +from elftools.elf.elffile import ELFFile + +f = open(sys.argv[-1], "rb") +ef = ELFFile(f) + +symtab = ef.get_section_by_name(".symtab") +symbols = {} +for s in symtab.iter_symbols(): + addr = s.entry["st_value"] + symbols[addr] = s.name +f.close() + +# sys.exit(0) + +decoder = sigrokdecode.get_decoder("arm_itm")() + +decoder.reset() +decoder.options = {"objdump": "", "elffile": ""} +decoder.start() + +dwt_timestamp = 0 +last_dwt_timestamp = 0 +streak = 0 +print("[") + +stack = [] + + +def emit(ts, addr, channel): + s = None + if addr in symbols: + s = symbols[addr] + else: + s = hex(addr) + if addr < 0x6000_0000: + s = "R:" + s + else: + s = "F:" + s + if channel[0] == "3": + stack.append(addr) + else: + if not stack or stack[-1] != addr: + return + stack.pop() + event = { + "name": s, + "ph": "B" if channel[0] == "3" else "E", + "ts": ts, + "pid": 0, + "tid": 0, + } + print(json.dumps(event), ",") + + +def decoder_cb(ss, es, data): + global streak + global last_dwt_timestamp + # print(ss, es, data) + ptype = data[0] + ts = (dwt_timestamp + (streak * 32)) / 500 + if ptype == 0: + event = {"name": data[1][0], "ph": "i", "ts": ts, "pid": 0, "tid": 0, "s": "g"} + print(json.dumps(event), ",") + if data[1][0] == "Overflow": + while stack: + emit(ts, stack[-1], "4:") + + if ptype in (0, 1): + return + if ptype == 2 and (data[1][0].startswith("3:") or data[1][0].startswith("4:")): + channel, addr = data[1][0].split() + addr = int(addr[2:], 16) + # if addr & 0x1 != 0: + # addr -= 1 + # print(dwt_timestamp + streak, channel, symbols[addr], hex(addr)) + emit(ts, addr, channel) + else: + # print(dwt_timestamp + streak, data) + pass + if dwt_timestamp == last_dwt_timestamp: + streak += 1 + else: + streak = 0 + + if last_dwt_timestamp > dwt_timestamp: + raise RuntimeError() + last_dwt_timestamp = dwt_timestamp + + +decoder.add_callback(sigrokdecode.OUTPUT_ANN, None, decoder_cb) + +s = serial.Serial(sys.argv[-2], 1000000) + + +buffers = [] +while True: + try: + start_ts = time.monotonic_ns() + b = s.read(s.in_waiting) + if b: + end_ts = time.monotonic_ns() + buffers.append((start_ts, end_ts, b)) + # print(len(b)) + # if len(buffers) > 10: + # break + except KeyboardInterrupt: + break + +time_per_bit = 1_000_000_000 / 1000000 + +min_gap = 100000000 +total_bytes = 0 +for start_ts, end_ts, buf in buffers: + # print(total_bytes, start_ts, end_ts, buf) + ts_per_byte = (end_ts - start_ts) / len(buf) + for i, b in enumerate(buf): + # print(total_bytes, hex(b)) + total_bytes += 1 + decoder.decode( + start_ts + ts_per_byte * i, start_ts + ts_per_byte * (i + 1), ("DATA", None, (b,)) + ) + dwt_timestamp = decoder.dwt_timestamp diff --git a/tools/swo_viewer.py b/tools/swo_viewer.py new file mode 100644 index 0000000000..327c450023 --- /dev/null +++ b/tools/swo_viewer.py @@ -0,0 +1,67 @@ +"""This prints out all parsed ITM packets. + +Connect a USB to Serial converter to the SWO pin and then provide the serial +device to this script. It should be 1MBaud SWO signal. CTRL-C when you've +captured enough data and then it'll process and output. + +pip install pysigrok-libsigrokdecode +python tools/swo_viewer.py /dev/ttyACM0 +""" + +import serial +import sys +import sigrokdecode +import time +import json + +decoder = sigrokdecode.get_decoder("arm_itm")() + +decoder.reset() +decoder.options = {"objdump": "", "elffile": ""} +decoder.start() + +dwt_timestamp = 0 +last_dwt_timestamp = 0 +streak = 0 + +stack = [] + + +def decoder_cb(ss, es, data): + global streak + global last_dwt_timestamp + print(dwt_timestamp, ss, es, data) + + +decoder.add_callback(sigrokdecode.OUTPUT_ANN, None, decoder_cb) + +s = serial.Serial(sys.argv[-2], 1000000) + +buffers = [] +while True: + try: + start_ts = time.monotonic_ns() + b = s.read(s.in_waiting) + if b: + end_ts = time.monotonic_ns() + buffers.append((start_ts, end_ts, b)) + # print(len(b)) + # if len(buffers) > 10: + # break + except KeyboardInterrupt: + break + +time_per_bit = 1_000_000_000 / 1000000 + +min_gap = 100000000 +total_bytes = 0 +for start_ts, end_ts, buf in buffers: + # print(total_bytes, start_ts, end_ts, buf) + ts_per_byte = (end_ts - start_ts) / len(buf) + for i, b in enumerate(buf): + # print(total_bytes, hex(b)) + total_bytes += 1 + decoder.decode( + start_ts + ts_per_byte * i, start_ts + ts_per_byte * (i + 1), ("DATA", None, (b,)) + ) + dwt_timestamp = decoder.dwt_timestamp diff --git a/tools/usb_descriptor b/tools/usb_descriptor deleted file mode 160000 index 2eaa6114b2..0000000000 --- a/tools/usb_descriptor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2eaa6114b209fe7f0a795eda8d6a7b3b93d76d2e