Merge branch 'adafruit:main' into adcdma

This commit is contained in:
Lee Atkinson 2022-08-18 09:08:10 -04:00 committed by GitHub
commit 34b8fbaf14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
80 changed files with 1199 additions and 350 deletions

View File

@ -202,6 +202,24 @@ Example:
curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/ curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
``` ```
##### Move
Moves the directory at the given path to ``X-Destination``. Also known as rename.
The custom `X-Destination` header stores the destination path of the directory.
* `201 Created` - Directory renamed
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Source directory not found or destination path is missing
* `409 Conflict` - USB is active and preventing file system modification
* `412 Precondition Failed` - The destination path is already in use
Example:
```sh
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello2/" -L --location-trusted http://circuitpython.local/fs/lib/hello/
```
##### DELETE ##### DELETE
Deletes the directory and all of its contents. Deletes the directory and all of its contents.
@ -214,7 +232,7 @@ Deletes the directory and all of its contents.
Example: Example:
```sh ```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world/ curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello2/world/
``` ```
@ -270,6 +288,25 @@ curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hel
``` ```
##### Move
Moves the file at the given path to the ``X-Destination``. Also known as rename.
The custom `X-Destination` header stores the destination path of the file.
* `201 Created` - File renamed
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Source file not found or destination path is missing
* `409 Conflict` - USB is active and preventing file system modification
* `412 Precondition Failed` - The destination path is already in use
Example:
```sh
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello/world2.txt" -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### DELETE ##### DELETE
Deletes the file. Deletes the file.
@ -283,7 +320,7 @@ Deletes the file.
Example: Example:
```sh ```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world2.txt
``` ```
### `/cp/` ### `/cp/`

View File

@ -6,14 +6,14 @@ msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n" "POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2022-05-20 19:25+0000\n" "PO-Revision-Date: 2022-08-14 12:14+0000\n"
"Last-Translator: Fabian Affolter <mail@fabian-affolter.ch>\n" "Last-Translator: Can Kocyigit <cank3698@googlemail.com>\n"
"Language: de_DE\n" "Language: de_DE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.13-dev\n" "X-Generator: Weblate 4.14-dev\n"
#: main.c #: main.c
msgid "" msgid ""
@ -82,7 +82,7 @@ msgstr ""
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c #: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q" msgid "%q"
msgstr "" msgstr "%q"
#: shared-bindings/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c
msgid "%q and %q contain duplicate pins" msgid "%q and %q contain duplicate pins"
@ -90,7 +90,7 @@ msgstr "%q und %q enthalten doppelte Pins"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "%q and %q must be different" msgid "%q and %q must be different"
msgstr "" msgstr "%q und %q müssen unterschiedlich sein"
#: shared-bindings/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c
msgid "%q contains duplicate pins" msgid "%q contains duplicate pins"
@ -114,11 +114,11 @@ msgstr "%q Indizes müssen Integer sein, nicht %s"
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
msgid "%q init failed" msgid "%q init failed"
msgstr "" msgstr "%q Initialisierung ist gescheitert"
#: py/argcheck.c #: py/argcheck.c
msgid "%q length must be %d" msgid "%q length must be %d"
msgstr "" msgstr "%q länge muss %d betragen"
#: py/argcheck.c #: py/argcheck.c
msgid "%q length must be %d-%d" msgid "%q length must be %d-%d"
@ -126,11 +126,11 @@ msgstr "%q Länge muss %d-%d sein"
#: py/argcheck.c #: py/argcheck.c
msgid "%q length must be <= %d" msgid "%q length must be <= %d"
msgstr "" msgstr "%q länge muss kleiner oder gleich %d sein"
#: py/argcheck.c #: py/argcheck.c
msgid "%q length must be >= %d" msgid "%q length must be >= %d"
msgstr "" msgstr "%q länge muss größer oder gleich %d sein"
#: shared-bindings/busio/I2C.c #: shared-bindings/busio/I2C.c
msgid "%q length must be >= 1" msgid "%q length must be >= 1"
@ -138,7 +138,7 @@ msgstr "%q Länge muss >= 1 sein"
#: py/argcheck.c #: py/argcheck.c
msgid "%q must be %d" msgid "%q must be %d"
msgstr "" msgstr "%q muss %d entsprechen"
#: py/argcheck.c #: py/argcheck.c
msgid "%q must be %d-%d" msgid "%q must be %d-%d"
@ -170,7 +170,7 @@ msgstr "%q muss ein String sein"
#: py/argcheck.c #: py/argcheck.c
msgid "%q must be an int" msgid "%q must be an int"
msgstr "" msgstr "%q muss vom Typ Integer sein"
#: py/argcheck.c #: py/argcheck.c
msgid "%q must be of type %q" msgid "%q must be of type %q"
@ -216,7 +216,7 @@ msgstr "%q, %q und %q müssen alle die gleiche Länge haben"
#: py/objint.c #: py/objint.c
msgid "%q=%q" msgid "%q=%q"
msgstr "" msgstr "%q=%q"
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
#, c-format #, c-format
@ -413,7 +413,7 @@ msgstr "Alle I2C-Peripheriegeräte sind in Benutzung"
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/espressif/common-hal/i2ctarget/I2CTarget.c
msgid "All I2C targets are in use" msgid "All I2C targets are in use"
msgstr "" msgstr "Alle I2C-Ziele sind in Verwendung"
#: ports/espressif/common-hal/countio/Counter.c #: ports/espressif/common-hal/countio/Counter.c
#: ports/espressif/common-hal/frequencyio/FrequencyIn.c #: ports/espressif/common-hal/frequencyio/FrequencyIn.c
@ -668,7 +668,7 @@ msgstr "Rufe super().__init__() vor dem Zugriff auf ein natives Objekt auf."
#: ports/cxd56/common-hal/camera/Camera.c #: ports/cxd56/common-hal/camera/Camera.c
msgid "Camera init" msgid "Camera init"
msgstr "" msgstr "Kamera Initialiserung"
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c #: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on RTC IO from deep sleep." msgid "Can only alarm on RTC IO from deep sleep."
@ -736,7 +736,7 @@ msgstr "'/' kann nicht wiedereingehängt werden, wenn per USB sichtbar."
#: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c
#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c
msgid "Cannot reset into bootloader because no bootloader is present" msgid "Cannot reset into bootloader because no bootloader is present"
msgstr "" msgstr "Kann nicht in den Bootloader resetten, weil keiner vorhanden ist"
#: ports/espressif/common-hal/socketpool/Socket.c #: ports/espressif/common-hal/socketpool/Socket.c
msgid "Cannot set socket options" msgid "Cannot set socket options"
@ -757,7 +757,7 @@ msgstr "Slice kann keine sub-klasse sein"
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins" msgid "Cannot transfer without MOSI and MISO pins"
msgstr "" msgstr "Kann nicht ohne MISO und MOSI Pins transferieren"
#: shared-bindings/pwmio/PWMOut.c #: shared-bindings/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use" msgid "Cannot vary frequency on a timer that is already in use"
@ -765,8 +765,9 @@ msgstr ""
"Die Frequenz eines bereits verwendeten Timers kann nicht variiert werden" "Die Frequenz eines bereits verwendeten Timers kann nicht variiert werden"
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c #: ports/nrf/common-hal/alarm/pin/PinAlarm.c
#, fuzzy
msgid "Cannot wake on pin edge, only level" msgid "Cannot wake on pin edge, only level"
msgstr "" msgstr "Kann nicht durch \"Pin edge\" geweckt werden nur durch \"level\""
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c #: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge. Only level." msgid "Cannot wake on pin edge. Only level."
@ -884,7 +885,7 @@ msgstr "Die Rotation der Anzeige muss in 90-Grad-Schritten erfolgen"
#: main.c #: main.c
msgid "Done" msgid "Done"
msgstr "" msgstr "Fertig"
#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/digitalio/DigitalInOut.c
msgid "Drive mode not used when direction is input." msgid "Drive mode not used when direction is input."
@ -959,7 +960,7 @@ msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x"
#: shared-module/rgbmatrix/RGBMatrix.c #: shared-module/rgbmatrix/RGBMatrix.c
msgid "Failed to allocate %q buffer" msgid "Failed to allocate %q buffer"
msgstr "" msgstr "Allokieren des %q Buffers ist fehlgeschlagen"
#: ports/espressif/common-hal/wifi/__init__.c #: ports/espressif/common-hal/wifi/__init__.c
msgid "Failed to allocate Wifi memory" msgid "Failed to allocate Wifi memory"
@ -1045,7 +1046,7 @@ msgstr "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
#: ports/cxd56/common-hal/gnss/GNSS.c #: ports/cxd56/common-hal/gnss/GNSS.c
msgid "GNSS init" msgid "GNSS init"
msgstr "" msgstr "GNSS Initialisierung"
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
msgid "Generic Failure" msgid "Generic Failure"
@ -1080,7 +1081,7 @@ msgstr "Lese/Schreibe-operation an geschlossener Datei"
#: ports/stm/common-hal/busio/I2C.c #: ports/stm/common-hal/busio/I2C.c
msgid "I2C init error" msgid "I2C init error"
msgstr "" msgstr "I2C Initialisierungsfehler"
#: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c
msgid "I2C peripheral in use" msgid "I2C peripheral in use"
@ -1195,7 +1196,7 @@ msgstr "Interner Fehler #%d"
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired." msgid "Internal watchdog timer expired."
msgstr "" msgstr "Der Interne WatchDog Timer ist abgelaufen."
#: py/argcheck.c #: py/argcheck.c
msgid "Invalid %q" msgid "Invalid %q"
@ -1278,11 +1279,11 @@ msgstr "LHS des Schlüsselwortarguments muss eine id sein"
#: shared-module/displayio/Group.c #: shared-module/displayio/Group.c
msgid "Layer already in a group" msgid "Layer already in a group"
msgstr "" msgstr "Ebene ist bereits in der Gruppe"
#: shared-module/displayio/Group.c #: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass" msgid "Layer must be a Group or TileGrid subclass"
msgstr "" msgstr "Ebene muss eine Gruppe oder eine TileGrid Subklasse sein"
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c #: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
msgid "MAC address was invalid" msgid "MAC address was invalid"
@ -1317,7 +1318,7 @@ msgstr "Fehlender MISO- oder MOSI-Pin"
#: ports/stm/common-hal/busio/SPI.c #: ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI pin" msgid "Missing MISO or MOSI pin"
msgstr "" msgstr "MISO oder MOSI Pin fehlt"
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format #, c-format
@ -1415,7 +1416,7 @@ msgstr "Kein I2C-Gerät an Adresse: 0x%x"
#: supervisor/shared/web_workflow/web_workflow.c #: supervisor/shared/web_workflow/web_workflow.c
msgid "No IP" msgid "No IP"
msgstr "" msgstr "Keine IP"
#: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c
@ -1424,7 +1425,7 @@ msgstr "Kein MISO-Pin"
#: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c
msgid "No MISO pin" msgid "No MISO pin"
msgstr "" msgstr "Miso Pin fehlt"
#: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/SPI.c
@ -1433,7 +1434,7 @@ msgstr "Kein MOSI-Pin"
#: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c #: ports/stm/common-hal/busio/SPI.c shared-module/bitbangio/SPI.c
msgid "No MOSI pin" msgid "No MOSI pin"
msgstr "" msgstr "MOSI Pin fehlt"
#: ports/atmel-samd/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c
#: ports/espressif/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c
@ -1574,11 +1575,11 @@ msgstr "Eine ungerade Parität wird nicht unterstützt"
#: supervisor/shared/bluetooth/bluetooth.c #: supervisor/shared/bluetooth/bluetooth.c
msgid "Off" msgid "Off"
msgstr "" msgstr "Aus"
#: supervisor/shared/bluetooth/bluetooth.c #: supervisor/shared/bluetooth/bluetooth.c
msgid "Ok" msgid "Ok"
msgstr "" msgstr "Ok"
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c
@ -1634,7 +1635,7 @@ msgstr "Nur eine Adresse ist erlaubt"
#: ports/nrf/common-hal/alarm/time/TimeAlarm.c #: ports/nrf/common-hal/alarm/time/TimeAlarm.c
#: ports/stm/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c
msgid "Only one alarm.time alarm can be set" msgid "Only one alarm.time alarm can be set"
msgstr "" msgstr "Nur ein alarm.time Alarm kann gesetzt werden"
#: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/espressif/common-hal/alarm/time/TimeAlarm.c
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c
@ -1684,7 +1685,7 @@ msgstr "Die PWM-Frequenz ist nicht schreibbar, wenn variable_Frequenz = False."
#: ports/stm/common-hal/pwmio/PWMOut.c #: ports/stm/common-hal/pwmio/PWMOut.c
msgid "PWM restart" msgid "PWM restart"
msgstr "" msgstr "PWM Neustart"
#: ports/raspberrypi/common-hal/countio/Counter.c #: ports/raspberrypi/common-hal/countio/Counter.c
msgid "PWM slice already in use" msgid "PWM slice already in use"
@ -1810,7 +1811,7 @@ msgstr "RNG Init-Fehler"
#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c
#: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c #: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "RS485" msgid "RS485"
msgstr "" msgstr "RS485"
#: ports/espressif/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c
#: ports/mimxrt10xx/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c
@ -1844,7 +1845,7 @@ msgstr "Erhaltene Antwort ist ungültig"
#: supervisor/shared/bluetooth/bluetooth.c #: supervisor/shared/bluetooth/bluetooth.c
msgid "Reconnecting" msgid "Reconnecting"
msgstr "" msgstr "Wiederherstellung der Verbindungen"
#: shared-bindings/displayio/EPaperDisplay.c #: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon" msgid "Refresh too soon"
@ -1876,7 +1877,7 @@ msgstr "SD-Card CSD-Format nicht unterstützt"
#: ports/cxd56/common-hal/sdioio/SDCard.c #: ports/cxd56/common-hal/sdioio/SDCard.c
msgid "SDCard init" msgid "SDCard init"
msgstr "" msgstr "SDCard Initialisierung"
#: ports/stm/common-hal/sdioio/SDCard.c #: ports/stm/common-hal/sdioio/SDCard.c
#, c-format #, c-format
@ -1894,7 +1895,7 @@ msgstr "SPI-Konfiguration fehlgeschlagen"
#: ports/stm/common-hal/busio/SPI.c #: ports/stm/common-hal/busio/SPI.c
msgid "SPI init error" msgid "SPI init error"
msgstr "" msgstr "SPI Initialisierungsfehler"
#: ports/raspberrypi/common-hal/busio/SPI.c #: ports/raspberrypi/common-hal/busio/SPI.c
msgid "SPI peripheral in use" msgid "SPI peripheral in use"
@ -1902,7 +1903,7 @@ msgstr "SPI-Peripheriegeräte wird bereits verwendet"
#: ports/stm/common-hal/busio/SPI.c #: ports/stm/common-hal/busio/SPI.c
msgid "SPI re-init" msgid "SPI re-init"
msgstr "" msgstr "SPI wird erneut initialisiert"
#: shared-bindings/is31fl3741/FrameBuffer.c #: shared-bindings/is31fl3741/FrameBuffer.c
msgid "Scale dimensions must divide by 3" msgid "Scale dimensions must divide by 3"
@ -2075,7 +2076,7 @@ msgstr "Zum beenden, resette bitte das board ohne "
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample" msgid "Too many channels in sample"
msgstr "" msgstr "Zu viele Kanäle im Beispiel"
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample." msgid "Too many channels in sample."
@ -2110,20 +2111,20 @@ msgstr "Tuple- oder struct_time-Argument erforderlich"
#: ports/stm/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c
msgid "UART de-init" msgid "UART de-init"
msgstr "" msgstr "UART wird de-initialisiert"
#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c
#: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "UART init" msgid "UART init"
msgstr "" msgstr "UART Initialisierung"
#: ports/stm/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c
msgid "UART re-init" msgid "UART re-init"
msgstr "" msgstr "UART wird wieder Initialisiert"
#: ports/stm/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c
msgid "UART write" msgid "UART write"
msgstr "" msgstr "UART wird geschrieben"
#: shared-module/usb_hid/Device.c #: shared-module/usb_hid/Device.c
msgid "USB busy" msgid "USB busy"
@ -2277,7 +2278,7 @@ msgstr "Nicht unterstütztes Format"
#: shared-bindings/hashlib/__init__.c #: shared-bindings/hashlib/__init__.c
msgid "Unsupported hash algorithm" msgid "Unsupported hash algorithm"
msgstr "" msgstr "Hash Algorithmus wird nicht unterstützt"
#: ports/espressif/common-hal/dualbank/__init__.c #: ports/espressif/common-hal/dualbank/__init__.c
msgid "Update Failed" msgid "Update Failed"
@ -2349,7 +2350,7 @@ msgstr ""
#: supervisor/shared/web_workflow/web_workflow.c #: supervisor/shared/web_workflow/web_workflow.c
msgid "Wi-Fi: " msgid "Wi-Fi: "
msgstr "" msgstr "Wi-Fi: "
#: main.c #: main.c
msgid "Woken up by alarm.\n" msgid "Woken up by alarm.\n"
@ -2446,7 +2447,7 @@ msgstr "Array- und Indexlänge müssen gleich sein"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "array has too many dimensions" msgid "array has too many dimensions"
msgstr "" msgstr "Das Array hat zu viele Dimensionen"
#: py/objarray.c shared-bindings/alarm/SleepMemory.c #: py/objarray.c shared-bindings/alarm/SleepMemory.c
#: shared-bindings/nvm/ByteArray.c #: shared-bindings/nvm/ByteArray.c
@ -2565,7 +2566,7 @@ msgstr "Kalibrierung ist Schreibgeschützt"
#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c
#: shared-module/vectorio/Rectangle.c #: shared-module/vectorio/Rectangle.c
msgid "can only have one parent" msgid "can only have one parent"
msgstr "" msgstr "kann nur ein Elternteil haben"
#: py/emitinlinethumb.c #: py/emitinlinethumb.c
msgid "can only have up to 4 parameters to Thumb assembly" msgid "can only have up to 4 parameters to Thumb assembly"
@ -2745,7 +2746,7 @@ msgstr "Umwandlung (cast)"
#: ports/stm/common-hal/pwmio/PWMOut.c #: ports/stm/common-hal/pwmio/PWMOut.c
msgid "channel re-init" msgid "channel re-init"
msgstr "" msgstr "Kanal wird erneut initialisiert"
#: shared-bindings/_stage/Text.c #: shared-bindings/_stage/Text.c
msgid "chars buffer too small" msgid "chars buffer too small"
@ -2827,7 +2828,7 @@ msgstr "Convolve Argumente dürfen nicht leer sein"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "corrupted file" msgid "corrupted file"
msgstr "" msgstr "Korrupte Datei"
#: extmod/ulab/code/numpy/poly.c #: extmod/ulab/code/numpy/poly.c
msgid "could not invert Vandermonde matrix" msgid "could not invert Vandermonde matrix"
@ -2924,7 +2925,7 @@ msgstr "leer"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "empty file" msgid "empty file"
msgstr "" msgstr "Leere Datei"
#: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c #: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap" msgid "empty heap"
@ -3199,7 +3200,7 @@ msgstr "Indizes müssen Integer, Slices oder Boolesche Listen sein"
#: ports/espressif/common-hal/busio/I2C.c #: ports/espressif/common-hal/busio/I2C.c
msgid "init I2C" msgid "init I2C"
msgstr "" msgstr "initialisiere I2C"
#: extmod/ulab/code/scipy/optimize/optimize.c #: extmod/ulab/code/scipy/optimize/optimize.c
msgid "initial values must be iterable" msgid "initial values must be iterable"
@ -3248,7 +3249,7 @@ msgstr "Eingabematrix ist singulär"
#: extmod/ulab/code/numpy/create.c #: extmod/ulab/code/numpy/create.c
msgid "input must be 1- or 2-d" msgid "input must be 1- or 2-d"
msgstr "" msgstr "Eingabe muss 1- oder 2-d sein"
#: extmod/ulab/code/numpy/carray/carray.c #: extmod/ulab/code/numpy/carray/carray.c
msgid "input must be a 1D ndarray" msgid "input must be a 1D ndarray"
@ -3340,7 +3341,7 @@ msgstr "ungültiger micropython decorator"
#: ports/espressif/common-hal/esp32_camera/Camera.c #: ports/espressif/common-hal/esp32_camera/Camera.c
msgid "invalid setting" msgid "invalid setting"
msgstr "" msgstr "Invalide Einstellung"
#: shared-bindings/random/__init__.c #: shared-bindings/random/__init__.c
msgid "invalid step" msgid "invalid step"
@ -3470,7 +3471,7 @@ msgstr "max_length muss 0-%d sein, wenn fixed_length %s ist"
#: extmod/ulab/code/ndarray.c #: extmod/ulab/code/ndarray.c
msgid "maximum number of dimensions is " msgid "maximum number of dimensions is "
msgstr "" msgstr "Maximale Anzahl an Dimensionen ist "
#: py/runtime.c #: py/runtime.c
msgid "maximum recursion depth exceeded" msgid "maximum recursion depth exceeded"
@ -3717,7 +3718,7 @@ msgstr "String mit ungerader Länge"
#: supervisor/shared/web_workflow/web_workflow.c #: supervisor/shared/web_workflow/web_workflow.c
msgid "off" msgid "off"
msgstr "" msgstr "aus"
#: extmod/ulab/code/utils/utils.c #: extmod/ulab/code/utils/utils.c
msgid "offset is too large" msgid "offset is too large"
@ -3874,15 +3875,15 @@ msgstr "pow() mit 3 Argumenten erfordert Integer"
#: ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h #: ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h
msgid "pressing BOOT button at start up.\n" msgid "pressing BOOT button at start up.\n"
msgstr "" msgstr "BOOT Taste wird beim Starten gedrückt.\n"
#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h #: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h
msgid "pressing SW38 button at start up.\n" msgid "pressing SW38 button at start up.\n"
msgstr "" msgstr "SW38 Taste wird beim Starten gedrückt.\n"
#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h #: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h
msgid "pressing VOLUME button at start up.\n" msgid "pressing VOLUME button at start up.\n"
msgstr "" msgstr "VOLUME Taste wird beim Starten gedrückt.\n"
#: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h #: ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.h
#: ports/espressif/boards/beetle-esp32-c3/mpconfigboard.h #: ports/espressif/boards/beetle-esp32-c3/mpconfigboard.h
@ -4153,7 +4154,7 @@ msgstr "Zeitlimit beim warten auf v2 Karte"
#: ports/stm/common-hal/pwmio/PWMOut.c #: ports/stm/common-hal/pwmio/PWMOut.c
msgid "timer re-init" msgid "timer re-init"
msgstr "" msgstr "Timer wird neu initialisiert"
#: shared-bindings/time/__init__.c #: shared-bindings/time/__init__.c
msgid "timestamp out of range for platform time_t" msgid "timestamp out of range for platform time_t"
@ -4329,11 +4330,11 @@ msgstr "nicht unterstützte Typen für %q: '%q', '%q'"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "usecols is too high" msgid "usecols is too high"
msgstr "" msgstr "usecols ist zu hoch/groß"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "usecols keyword must be specified" msgid "usecols keyword must be specified"
msgstr "" msgstr "usecols muss definiert sein"
#: py/objint.c #: py/objint.c
#, c-format #, c-format
@ -4378,7 +4379,7 @@ msgstr "falsche Achse gewählt"
#: extmod/ulab/code/numpy/io/io.c #: extmod/ulab/code/numpy/io/io.c
msgid "wrong dtype" msgid "wrong dtype"
msgstr "" msgstr "Falsches dtype"
#: extmod/ulab/code/numpy/transform.c #: extmod/ulab/code/numpy/transform.c
msgid "wrong index type" msgid "wrong index type"
@ -4396,7 +4397,7 @@ msgstr "falsche Länge des Array von Bedingungen"
#: extmod/ulab/code/numpy/transform.c #: extmod/ulab/code/numpy/transform.c
msgid "wrong length of index array" msgid "wrong length of index array"
msgstr "" msgstr "Falsche Länge des Index Arrays"
#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c
msgid "wrong number of arguments" msgid "wrong number of arguments"

View File

@ -6,7 +6,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n" "POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2022-08-07 15:16+0000\n" "PO-Revision-Date: 2022-08-11 17:18+0000\n"
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n" "Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n" "Language: sv\n"
@ -412,7 +412,7 @@ msgstr "All I2C-kringutrustning används"
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/espressif/common-hal/i2ctarget/I2CTarget.c
msgid "All I2C targets are in use" msgid "All I2C targets are in use"
msgstr "" msgstr "Alla I2C-mål används"
#: ports/espressif/common-hal/countio/Counter.c #: ports/espressif/common-hal/countio/Counter.c
#: ports/espressif/common-hal/frequencyio/FrequencyIn.c #: ports/espressif/common-hal/frequencyio/FrequencyIn.c
@ -3314,7 +3314,7 @@ msgstr "ogiltig mikropython-dekorator"
#: ports/espressif/common-hal/esp32_camera/Camera.c #: ports/espressif/common-hal/esp32_camera/Camera.c
msgid "invalid setting" msgid "invalid setting"
msgstr "" msgstr "ogiltig inställning"
#: shared-bindings/random/__init__.c #: shared-bindings/random/__init__.c
msgid "invalid step" msgid "invalid step"

View File

@ -7,15 +7,15 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2022-04-19 17:07+0000\n" "PO-Revision-Date: 2022-08-14 12:14+0000\n"
"Last-Translator: Siyabend Ürün <urunsiyabend@gmail.com>\n" "Last-Translator: Can Kocyigit <cank3698@googlemail.com>\n"
"Language-Team: none\n" "Language-Team: none\n"
"Language: tr\n" "Language: tr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.12-dev\n" "X-Generator: Weblate 4.14-dev\n"
#: main.c #: main.c
msgid "" msgid ""
@ -86,7 +86,7 @@ msgstr ""
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c #: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c #: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q" msgid "%q"
msgstr "" msgstr "%q"
#: shared-bindings/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c
msgid "%q and %q contain duplicate pins" msgid "%q and %q contain duplicate pins"
@ -94,7 +94,7 @@ msgstr "%q ve %q yinelenen pinler içeriyor"
#: ports/atmel-samd/common-hal/audioio/AudioOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c
msgid "%q and %q must be different" msgid "%q and %q must be different"
msgstr "" msgstr "%q ve %q farklı olmalılar"
#: shared-bindings/microcontroller/Pin.c #: shared-bindings/microcontroller/Pin.c
msgid "%q contains duplicate pins" msgid "%q contains duplicate pins"

2
main.c
View File

@ -543,7 +543,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
} }
// If interrupted by keyboard, return // If interrupted by keyboard, return
if (serial_connected() && serial_bytes_available()) { if (serial_connected() && serial_bytes_available() && !autoreload_pending()) {
// Skip REPL if reload was requested. // Skip REPL if reload was requested.
skip_repl = serial_read() == CHAR_CTRL_D; skip_repl = serial_read() == CHAR_CTRL_D;
if (skip_repl) { if (skip_repl) {

View File

@ -56,9 +56,9 @@ void board_init(void) {
bus->base.type = &displayio_fourwire_type; bus->base.type = &displayio_fourwire_type;
common_hal_displayio_fourwire_construct(bus, common_hal_displayio_fourwire_construct(bus,
spi, spi,
&pin_GPIO39, // TFT_DC Command or data &pin_GPIO40, // TFT_DC Command or data
&pin_GPIO40, // TFT_CS Chip select &pin_GPIO39, // TFT_CS Chip select
&pin_GPIO41, // TFT_RESET Reset &pin_GPIO38, // TFT_RESET Reset
40000000, // Baudrate 40000000, // Baudrate
0, // Polarity 0, // Polarity
0); // Phase 0); // Phase
@ -87,7 +87,7 @@ void board_init(void) {
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
display_init_sequence, display_init_sequence,
sizeof(display_init_sequence), sizeof(display_init_sequence),
&pin_GPIO38, // backlight pin &pin_GPIO41, // backlight pin
NO_BRIGHTNESS_COMMAND, NO_BRIGHTNESS_COMMAND,
1.0f, // brightness 1.0f, // brightness
false, // single_byte_bounds false, // single_byte_bounds

View File

@ -30,7 +30,9 @@
#define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) #define MICROPY_HW_NEOPIXEL (&pin_GPIO21)
#define MICROPY_HW_NEOPIXEL_COUNT (6) #define MICROPY_HW_NEOPIXEL_COUNT (1)
#define MICROPY_HW_LED_STATUS (&pin_GPIO1)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34)

View File

@ -24,13 +24,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) },
{ MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO40) },
{ MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO39) },
{ MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO41) }, { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO38) },
{ MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO4) }, { MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_CARD_POWER), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_IRQ), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_IRQ), MP_ROM_PTR(&pin_GPIO3) },
@ -39,7 +38,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO45) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO18) },

View File

@ -49,17 +49,5 @@ void board_deinit(void) {
} }
bool espressif_board_reset_pin_number(gpio_num_t pin_number) { bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Pull LED down on reset rather than the default up
if (pin_number == 13) {
gpio_config_t cfg = {
.pin_bit_mask = BIT64(pin_number),
.mode = GPIO_MODE_DISABLE,
.pull_up_en = false,
.pull_down_en = true,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return true;
}
return false; return false;
} }

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO0) #define MICROPY_HW_NEOPIXEL (&pin_GPIO0)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO2) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO2)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C (1)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO20, .sda = &pin_GPIO22}} #define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO20, .sda = &pin_GPIO22}}

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3)

View File

@ -141,18 +141,6 @@ bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
gpio_set_level(21, true); gpio_set_level(21, true);
return true; return true;
} }
// Pull LED down on reset rather than the default up
if (pin_number == 13) {
gpio_config_t cfg = {
.pin_bit_mask = BIT64(pin_number),
.mode = GPIO_MODE_DISABLE,
.pull_up_en = false,
.pull_down_en = true,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return true;
}
return false; return false;
} }

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO21)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO34)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42)

View File

@ -33,6 +33,8 @@
#define MICROPY_HW_APA102_SCK (&pin_GPIO15) #define MICROPY_HW_APA102_SCK (&pin_GPIO15)
#define MICROPY_HW_APA102_COUNT (5) #define MICROPY_HW_APA102_COUNT (5)
#define MICROPY_HW_LED_STATUS (&pin_GPIO37)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO33) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO33)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO34) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO34)

View File

@ -34,6 +34,8 @@
#define CIRCUITPY_STATUS_LED_POWER_INVERTED (1) #define CIRCUITPY_STATUS_LED_POWER_INVERTED (1)
#define MICROPY_HW_NEOPIXEL_COUNT (4) #define MICROPY_HW_NEOPIXEL_COUNT (4)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33)

View File

@ -31,6 +31,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO45) #define MICROPY_HW_NEOPIXEL (&pin_GPIO45)
#define MICROPY_HW_LED_STATUS (&pin_GPIO42)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33)

View File

@ -30,7 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" #define MICROPY_HW_MCU_NAME "ESP32-C3FN4"
// Status LED // Status LED
#define MICROPY_HW_NEOPIXEL (&pin_GPIO10) #define MICROPY_HW_LED_STATUS (&pin_GPIO10)
#define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C (1)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO9, .sda = &pin_GPIO8}} #define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO9, .sda = &pin_GPIO8}}

View File

@ -28,3 +28,7 @@
#define MICROPY_HW_BOARD_NAME "CrumpS2" #define MICROPY_HW_BOARD_NAME "CrumpS2"
#define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
#define MICROPY_HW_APA102_SCK (&pin_GPIO45)
#define MICROPY_HW_APA102_COUNT (1)

View File

@ -30,7 +30,8 @@
#define MICROPY_HW_MCU_NAME "ESP32S3" #define MICROPY_HW_MCU_NAME "ESP32S3"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO46) #define MICROPY_HW_NEOPIXEL (&pin_GPIO46)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO13)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO41)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO42) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO42)

View File

@ -28,3 +28,5 @@
#define MICROPY_HW_BOARD_NAME "BastWiFi" #define MICROPY_HW_BOARD_NAME "BastWiFi"
#define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_LED_STATUS (&pin_GPIO14)

View File

@ -44,3 +44,18 @@ void reset_board(void) {
void board_deinit(void) { void board_deinit(void) {
} }
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Pull LEDs down on reset rather than the default up
if (pin_number == 21 || pin_number == 22) {
gpio_config_t cfg = {
.pin_bit_mask = BIT64(pin_number),
.mode = GPIO_MODE_DISABLE,
.pull_up_en = false,
.pull_down_en = true,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return true;
}
return false;
}

View File

@ -29,6 +29,8 @@
#define MICROPY_HW_BOARD_NAME "Espressif ESP32-EYE" #define MICROPY_HW_BOARD_NAME "Espressif ESP32-EYE"
#define MICROPY_HW_MCU_NAME "ESP32" #define MICROPY_HW_MCU_NAME "ESP32"
#define MICROPY_HW_LED_STATUS (&pin_GPIO21)
#define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C (1)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO23, .sda = &pin_GPIO18}} #define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO23, .sda = &pin_GPIO18}}

View File

@ -46,7 +46,6 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO43) },
{ MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO44) },
{ MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO48) }, { MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO48) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },

View File

@ -31,5 +31,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) #define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define MICROPY_HW_LED_STATUS (&pin_GPIO2)
#define MICROPY_HW_LED_STATUS_INVERTED (1)
#define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DEFAULT_UART_BUS_TX (&pin_GPIO43)
#define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_RX (&pin_GPIO44)

View File

@ -31,6 +31,9 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) #define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define MICROPY_HW_LED_STATUS (&pin_GPIO2)
#define MICROPY_HW_LED_STATUS_INVERTED (1)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO40)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO41)

View File

@ -31,5 +31,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) #define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define MICROPY_HW_LED_STATUS (&pin_GPIO2)
#define MICROPY_HW_LED_STATUS_INVERTED (1)
#define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DEFAULT_UART_BUS_TX (&pin_GPIO43)
#define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_RX (&pin_GPIO44)

View File

@ -31,6 +31,9 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) #define MICROPY_HW_NEOPIXEL (&pin_GPIO18)
#define MICROPY_HW_LED_STATUS (&pin_GPIO2)
#define MICROPY_HW_LED_STATUS_INVERTED (1)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO40) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO40)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO41) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO41)

View File

@ -30,7 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_MCU_NAME "ESP32S2"
#define MICROPY_HW_NEOPIXEL (&pin_GPIO40) #define MICROPY_HW_NEOPIXEL (&pin_GPIO40)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) #define MICROPY_HW_LED_STATUS (&pin_GPIO39)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8)

View File

@ -15,22 +15,6 @@ bool board_requests_safe_mode(void) {
return false; return false;
} }
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Pull LED down on reset rather than the default up
if (pin_number == MICROPY_HW_LED_STATUS->number) {
gpio_config_t cfg = {
.pin_bit_mask = BIT64(pin_number),
.mode = GPIO_MODE_DISABLE,
.pull_up_en = false,
.pull_down_en = true,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return true;
}
return false;
}
void reset_board(void) { void reset_board(void) {
} }

View File

@ -15,22 +15,6 @@ bool board_requests_safe_mode(void) {
return false; return false;
} }
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Pull LED down on reset rather than the default up
if (pin_number == MICROPY_HW_LED_STATUS->number) {
gpio_config_t cfg = {
.pin_bit_mask = BIT64(pin_number),
.mode = GPIO_MODE_DISABLE,
.pull_up_en = false,
.pull_down_en = true,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&cfg);
return true;
}
return false;
}
void reset_board(void) { void reset_board(void) {
} }

View File

@ -29,6 +29,8 @@
#define MICROPY_HW_BOARD_NAME "S2Mini" #define MICROPY_HW_BOARD_NAME "S2Mini"
#define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP #define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP
#define MICROPY_HW_LED_STATUS (&pin_GPIO15)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO35) // no I2C labels on S2 Mini, def from Wemos MP #define DEFAULT_I2C_BUS_SCL (&pin_GPIO35) // no I2C labels on S2 Mini, def from Wemos MP
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) // no I2C labels on S2 Mini, def from Wemos MP #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) // no I2C labels on S2 Mini, def from Wemos MP

View File

@ -29,6 +29,8 @@
#define MICROPY_HW_BOARD_NAME "S2Pico" #define MICROPY_HW_BOARD_NAME "S2Pico"
#define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP #define MICROPY_HW_MCU_NAME "ESP32S2-S2FN4R2" // from Wemos MP
#define MICROPY_HW_LED_STATUS (&pin_GPIO10)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) // JST SH Connector Pin 3 NOT STEMMA QT / Feather pinout #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) // JST SH Connector Pin 3 NOT STEMMA QT / Feather pinout
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) // JST SH Connector Pin 2 NOT STEMMA QT / Feather pinout #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) // JST SH Connector Pin 2 NOT STEMMA QT / Feather pinout

View File

@ -28,10 +28,12 @@
#define MICROPY_HW_BOARD_NAME "MicroDev microC3" #define MICROPY_HW_BOARD_NAME "MicroDev microC3"
#define MICROPY_HW_MCU_NAME "ESP32-C3FN4" #define MICROPY_HW_MCU_NAME "ESP32-C3FN4"
// Status LED // Status LEDs
#define MICROPY_HW_NEOPIXEL (&pin_GPIO7) #define MICROPY_HW_NEOPIXEL (&pin_GPIO7)
#define MICROPY_HW_NEOPIXEL_COUNT (2) #define MICROPY_HW_NEOPIXEL_COUNT (2)
#define MICROPY_HW_LED_STATUS (&pin_GPIO8)
// Default bus pins // Default bus pins
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO5)

View File

@ -42,17 +42,6 @@ bool board_requests_safe_mode(void) {
return false; return false;
} }
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Pin 21 is a high side LED so pull it down to prevent lighting the LED.
if (pin_number == 21) {
gpio_reset_pin(21);
gpio_pullup_dis(21);
gpio_pulldown_en(21);
return true;
}
return false;
}
void reset_board(void) { void reset_board(void) {
} }

View File

@ -28,9 +28,11 @@
#define MICROPY_HW_BOARD_NAME "MicroDev microS2" #define MICROPY_HW_BOARD_NAME "MicroDev microS2"
#define MICROPY_HW_MCU_NAME "ESP32-S2" #define MICROPY_HW_MCU_NAME "ESP32-S2"
// Status LED // Status LEDs
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) #define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#define MICROPY_HW_LED_STATUS (&pin_GPIO21)
// Default bus pins // Default bus pins
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO1)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO2)

View File

@ -31,5 +31,7 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO45) #define MICROPY_HW_NEOPIXEL (&pin_GPIO45)
#define MICROPY_HW_LED_STATUS (&pin_GPIO21)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO34) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO34)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33)

View File

@ -32,6 +32,8 @@
// #define MICROPY_HW_APA102_MOSI (&pin_GPIO40) // #define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
// #define MICROPY_HW_APA102_SCK (&pin_GPIO45) // #define MICROPY_HW_APA102_SCK (&pin_GPIO45)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO40) #define MICROPY_HW_NEOPIXEL (&pin_GPIO40)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8)

View File

@ -32,6 +32,8 @@
// #define MICROPY_HW_APA102_MOSI (&pin_GPIO40) // #define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
// #define MICROPY_HW_APA102_SCK (&pin_GPIO45) // #define MICROPY_HW_APA102_SCK (&pin_GPIO45)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO38) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO38)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO33)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO40) #define MICROPY_HW_NEOPIXEL (&pin_GPIO40)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39) #define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO39)
#define MICROPY_HW_LED_STATUS (&pin_GPIO13)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8)

View File

@ -0,0 +1,153 @@
/*
* 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 Adafruit_CircuitPython_ST7735R
// https://github.com/adafruit/Adafruit_CircuitPython_ST7735R
uint8_t display_init_sequence[] = {
// sw reset
0x01, 0 | DELAY, 0x96,
// SLPOUT and Delay
0x11, 0 | DELAY, 0xFF,
0xB1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1
0xB3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3
0xB4, 0x01, 0x07, // _INVCTR line inversion
0xC0, 0x03, 0xA2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA
0xC1, 0x01, 0xC5, // _PWCTR2 VGH=14.7V, VGL=-7.35V
0xC2, 0x02, 0x0A, 0x00, // _PWCTR3 Opamp current small, Boost frequency
0xC3, 0x02, 0x8A, 0x2A,
0xC4, 0x02, 0x8A, 0xEE,
0xC5, 0x01, 0x0E, // _VMCTR1 VCOMH = 4V, VOML = -1.1V
0x20, 0x00, // _INVOFF
0x36, 0x01, 0x18, // _MADCTL bottom to top refresh
// 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
// fix on VTL
0x3A, 0x01, 0x05, // COLMOD - 16bit color
0xE0, 0x10, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma
0xE1, 0x10, 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1
0x13, 0 | DELAY, 0x0A, // _NORON
0x29, 0 | DELAY, 0x64, // _DISPON
// 0x36, 0x01, 0xC0, // _MADCTL Default rotation plus BGR encoding
0x36, 0x01, 0xC8, // _MADCTL Default rotation plus RGB encoding
0x21, 0x00, // _INVON
};
static void display_init(void) {
busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus;
common_hal_busio_spi_construct(
spi,
&pin_GPIO10, // CLK
&pin_GPIO11, // 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_GPIO18, // DC
&pin_GPIO9, // CS
&pin_GPIO21, // RST
40000000, // baudrate
0, // polarity
0 // phase
);
displayio_display_obj_t *display = &displays[0].display;
display->base.type = &displayio_display_type;
// workaround as board_init() is called before reset_port() in main.c
pwmout_reset();
common_hal_displayio_display_construct(
display,
bus,
160, // width (after rotation)
80, // height (after rotation)
26, // column start
1, // row start
90, // rotation
16, // color depth
false, // grayscale
false, // pixels in a byte share a row. Only valid for depths < 8
1, // bytes per cell. Only valid for depths < 8
false, // reverse_pixels_in_byte. Only valid for depths < 8
true, // reverse_pixels_in_word
MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command
MIPI_COMMAND_WRITE_MEMORY_START, // write memory command
display_init_sequence,
sizeof(display_init_sequence),
&pin_GPIO45, // 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
);
common_hal_never_reset_pin(&pin_GPIO45); // backlight pin
}
void board_init(void) {
// Debug UART
#ifdef DEBUG
common_hal_never_reset_pin(&pin_GPIO43);
common_hal_never_reset_pin(&pin_GPIO44);
#endif /* DEBUG */
// Display
display_init();
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}
void board_deinit(void) {
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Micropython setup
#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S2-Pico-LCD"
#define MICROPY_HW_MCU_NAME "ESP32S2"
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO41)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO40)
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10)
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11)
#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12)
#define DEFAULT_UART_BUS_RX (&pin_GPIO44)
#define DEFAULT_UART_BUS_TX (&pin_GPIO43)

View File

@ -0,0 +1,18 @@
USB_VID = 0x303a
USB_PID = 0x810c
USB_PRODUCT = "ESP32-S2-Pico-LCD"
USB_MANUFACTURER = "Waveshare Electronics"
IDF_TARGET = esp32s2
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
# The default queue depth of 16 overflows on release builds,
# so increase it to 32.
CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
CIRCUITPY_ESP_FLASH_MODE=dio
CIRCUITPY_ESP_FLASH_FREQ=80m
CIRCUITPY_ESP_FLASH_SIZE=4MB

View File

@ -0,0 +1,79 @@
#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_BUTTON), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_USB_IN), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) },
{ MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) },
{ MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) },
{ MP_ROM_QSTR(MP_QSTR_GP37), MP_ROM_PTR(&pin_GPIO37) },
{ MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) },
{ MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO40) },
{ MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) },
{ MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) },
{ MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) },
// 0.96 inch LCD ST7735s
{ MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO45) },
{ MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -0,0 +1,37 @@
CONFIG_ESP32S2_SPIRAM_SUPPORT=y
#
# SPI RAM config
#
# CONFIG_SPIRAM_TYPE_AUTO is not set
# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set
# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
CONFIG_SPIRAM_SIZE=8388608
# end of SPI RAM config
CONFIG_DEFAULT_PSRAM_CLK_IO=30
#
# PSRAM clock and cs IO for ESP32S2
#
CONFIG_DEFAULT_PSRAM_CS_IO=26
# end of PSRAM clock and cs IO for ESP32S2
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
# CONFIG_SPIRAM_RODATA is not set
CONFIG_SPIRAM_SPEED_80M=y
# CONFIG_SPIRAM_SPEED_40M is not set
# CONFIG_SPIRAM_SPEED_26M is not set
# CONFIG_SPIRAM_SPEED_20M is not set
CONFIG_SPIRAM=y
CONFIG_SPIRAM_BOOT_INIT=y
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
CONFIG_SPIRAM_USE_MEMMAP=y
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
# CONFIG_SPIRAM_USE_MALLOC is not set
CONFIG_SPIRAM_MEMTEST=y
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
#
# LWIP
#
CONFIG_LWIP_LOCAL_HOSTNAME="waveshare"
# end of LWIP

View File

@ -29,4 +29,4 @@
#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S2-Pico" #define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S2-Pico"
#define MICROPY_HW_MCU_NAME "ESP32S2" #define MICROPY_HW_MCU_NAME "ESP32S2"
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO9) #define MICROPY_HW_LED_STATUS (&pin_GPIO9)

View File

@ -130,15 +130,26 @@ STATIC void _reset_pin(gpio_num_t pin_number) {
return; return;
} }
gpio_reset_pin(pin_number); bool pull_down = false;
// Special case the status LED pin.
#if defined(MICROPY_HW_LED_STATUS) && (!defined(MICROPY_HW_LED_STATUS_INVERTED) || !MICROPY_HW_LED_STATUS_INVERTED)
pull_down = pull_down || pin_number == MICROPY_HW_LED_STATUS->number;
#endif
#ifdef DOUBLE_TAP_PIN #ifdef DOUBLE_TAP_PIN
// Pull the double tap pin down so that resets come back to CircuitPython. // Pull the double tap pin down so that resets come back to CircuitPython.
if (pin_number == DOUBLE_TAP_PIN->number) { pull_down = pull_down || pin_number == DOUBLE_TAP_PIN->number;
#endif
// This will pull the pin up. For pins needing pull down it shouldn't be a
// problem for a moment.
gpio_reset_pin(pin_number);
if (pull_down) {
gpio_pullup_dis(pin_number); gpio_pullup_dis(pin_number);
gpio_pulldown_en(pin_number); gpio_pulldown_en(pin_number);
} }
#endif
} }
// Mark pin as free and return it to a quiescent state. // Mark pin as free and return it to a quiescent state.

View File

@ -30,22 +30,9 @@
#include "peripherals/touch.h" #include "peripherals/touch.h"
#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h"
static uint16_t get_raw_reading(touchio_touchin_obj_t *self) {
#if defined(CONFIG_IDF_TARGET_ESP32)
uint16_t touch_value;
#else
uint32_t touch_value;
#endif;
touch_pad_read_raw_data(self->pin->touch_channel, &touch_value);
if (touch_value > UINT16_MAX) {
return UINT16_MAX;
}
return (uint16_t)touch_value;
}
void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
const mcu_pin_obj_t *pin) { const mcu_pin_obj_t *pin) {
if (pin->touch_channel == TOUCH_PAD_MAX) { if (pin->touch_channel == NO_TOUCH_CHANNEL) {
raise_ValueError_invalid_pin(); raise_ValueError_invalid_pin();
} }
claim_pin(pin); claim_pin(pin);
@ -53,15 +40,12 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
// initialize touchpad // initialize touchpad
peripherals_touch_init(pin->touch_channel); peripherals_touch_init(pin->touch_channel);
// wait for touch data to reset
mp_hal_delay_ms(10);
// Set a "touched" threshold not too far above the initial value. // Set a "touched" threshold not too far above the initial value.
// For simple finger touch, the values may vary as much as a factor of two, // For simple finger touch, the values may vary as much as a factor of two,
// but for touches using fruit or other objects, the difference is much less. // but for touches using fruit or other objects, the difference is much less.
self->pin = pin; self->pin = pin;
self->threshold = get_raw_reading(self) + 100; self->threshold = common_hal_touchio_touchin_get_raw_value(self) + 100;
} }
bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self) { bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self) {
@ -77,11 +61,11 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self) {
} }
bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) {
return get_raw_reading(self) > self->threshold; return common_hal_touchio_touchin_get_raw_value(self) > self->threshold;
} }
uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) { uint16_t common_hal_touchio_touchin_get_raw_value(touchio_touchin_obj_t *self) {
return get_raw_reading(self); return peripherals_touch_read(self->pin->touch_channel);
} }
uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) { uint16_t common_hal_touchio_touchin_get_threshold(touchio_touchin_obj_t *self) {

View File

@ -43,7 +43,7 @@ void peripherals_touch_never_reset(const bool enable) {
void peripherals_touch_init(const touch_pad_t touchpad) { void peripherals_touch_init(const touch_pad_t touchpad) {
if (!touch_inited) { if (!touch_inited) {
touch_pad_init(); touch_pad_init();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW);
} }
// touch_pad_config() must be done before touch_pad_fsm_start() the first time. // touch_pad_config() must be done before touch_pad_fsm_start() the first time.
// Otherwise the calibration is wrong and we get maximum raw values if there is // Otherwise the calibration is wrong and we get maximum raw values if there is
@ -52,13 +52,27 @@ void peripherals_touch_init(const touch_pad_t touchpad) {
touch_pad_config(touchpad, 0); touch_pad_config(touchpad, 0);
#else #else
touch_pad_config(touchpad); touch_pad_config(touchpad);
#endif
if (!touch_inited) {
#if defined(CONFIG_IDF_TARGET_ESP32)
touch_pad_sw_start();
#else
touch_pad_fsm_start(); touch_pad_fsm_start();
#endif #endif
touch_inited = true; touch_inited = true;
} }
uint16_t peripherals_touch_read(touch_pad_t touchpad) {
#if defined(CONFIG_IDF_TARGET_ESP32)
uint16_t touch_value;
touch_pad_read(touchpad, &touch_value);
// ESP32 touch_pad_read() returns a lower value when a pin is touched instead of a higher value.
// Flip the values around to be consistent with TouchIn assumptions.
return UINT16_MAX - touch_value;
#else
uint32_t touch_value;
touch_pad_sw_start();
while (!touch_pad_meas_is_done()) {
}
touch_pad_read_raw_data(touchpad, &touch_value);
if (touch_value > UINT16_MAX) {
return UINT16_MAX;
}
return (uint16_t)touch_value;
#endif
} }

View File

@ -29,6 +29,7 @@
#include "driver/touch_pad.h" #include "driver/touch_pad.h"
extern uint16_t peripherals_touch_read(touch_pad_t touchpad);
extern void peripherals_touch_reset(void); extern void peripherals_touch_reset(void);
extern void peripherals_touch_never_reset(const bool enable); extern void peripherals_touch_never_reset(const bool enable);
extern void peripherals_touch_init(const touch_pad_t touchpad); extern void peripherals_touch_init(const touch_pad_t touchpad);

View File

@ -345,9 +345,6 @@ void reset_port(void) {
reset_all_pins(); reset_all_pins();
// A larger delay so the idle task can run and do any IDF cleanup needed.
vTaskDelay(4);
#if CIRCUITPY_ANALOGIO #if CIRCUITPY_ANALOGIO
analogout_reset(); analogout_reset();
#endif #endif
@ -402,6 +399,9 @@ void reset_port(void) {
#if CIRCUITPY_WATCHDOG #if CIRCUITPY_WATCHDOG
watchdog_reset(); watchdog_reset();
#endif #endif
// Yield so the idle task can run and do any IDF cleanup needed.
port_yield();
} }
void reset_to_bootloader(void) { void reset_to_bootloader(void) {
@ -492,6 +492,10 @@ void port_wake_main_task_from_isr() {
} }
} }
void port_yield() {
vTaskDelay(4);
}
void sleep_timer_cb(void *arg) { void sleep_timer_cb(void *arg) {
port_wake_main_task(); port_wake_main_task();
} }

View File

@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "supervisor/board.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
void reset_board(void) {
}
void board_deinit(void) {
}

View File

@ -0,0 +1,7 @@
#define MICROPY_HW_BOARD_NAME "BBQ20KBD"
#define MICROPY_HW_MCU_NAME "rp2040"
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO23)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO18)
#define DEFAULT_UART_BUS_TX (&pin_GPIO20)

View File

@ -0,0 +1,13 @@
USB_VID = 0x1209
USB_PID = 0xB182
USB_PRODUCT = "BBQ20 Keyboard"
USB_MANUFACTURER = "Solder Party"
CHIP_VARIANT = RP2040
CHIP_FAMILY = rp2
EXTERNAL_FLASH_DEVICES = "GD25Q16C"
CIRCUITPY__EVE = 1
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID

View File

@ -0,0 +1 @@
// Put board-specific pico-sdk definitions here. This file must exist.

View File

@ -0,0 +1,41 @@
#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_INT), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_PERIPHERAL_SDA), MP_ROM_PTR(&pin_GPIO28) },
{ MP_ROM_QSTR(MP_QSTR_PERIPHERAL_SCL), MP_ROM_PTR(&pin_GPIO29) },
{ MP_ROM_QSTR(MP_QSTR_ROW1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_ROW2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_ROW3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_ROW4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_ROW5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_ROW6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_ROW7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_COL1), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_COL2), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_COL3), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_COL4), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_COL5), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_COL6), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_BTN1), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_GPIO25) },
{ MP_ROM_QSTR(MP_QSTR_TP_RESET), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_TP_MOTION), MP_ROM_PTR(&pin_GPIO22) },
{ MP_ROM_QSTR(MP_QSTR_TP_SHUTDOWN), MP_ROM_PTR(&pin_GPIO24) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO23) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -0,0 +1,156 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/i2ctarget/I2CTarget.h"
#include "common-hal/busio/I2C.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "shared-bindings/busio/I2C.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "py/runtime.h"
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h"
STATIC i2c_inst_t *i2c[2] = {i2c0, i2c1};
#define NO_PIN 0xff
void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
uint8_t *addresses, unsigned int num_addresses, bool smbus) {
self->peripheral = NULL;
// I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs
// so we can divide by two to get the instance. This pattern repeats.
size_t scl_instance = (scl->number / 2) % 2;
size_t sda_instance = (sda->number / 2) % 2;
if (scl->number % 2 == 1 && sda->number % 2 == 0 && scl_instance == sda_instance) {
self->peripheral = i2c[sda_instance];
}
if (self->peripheral == NULL) {
raise_ValueError_invalid_pins();
}
if ((i2c_get_hw(self->peripheral)->enable & I2C_IC_ENABLE_ENABLE_BITS) != 0) {
mp_raise_ValueError(translate("I2C peripheral in use"));
}
if (num_addresses > 1) {
mp_raise_ValueError(translate("Only one address is allowed"));
}
self->addresses = addresses;
self->num_addresses = num_addresses;
self->scl_pin = scl->number;
self->sda_pin = sda->number;
// Have to specify a baudrate even if the i2c target does not use it
const uint32_t frequency = 400000;
i2c_init(self->peripheral, frequency);
gpio_set_function(sda->number, GPIO_FUNC_I2C);
gpio_set_function(scl->number, GPIO_FUNC_I2C);
gpio_set_pulls(sda->number, true, false);
gpio_set_pulls(scl->number, true, false);
self->peripheral->hw->intr_mask |= I2C_IC_INTR_MASK_M_RESTART_DET_BITS;
i2c_set_slave_mode(self->peripheral, true, self->addresses[0]);
return;
}
bool common_hal_i2ctarget_i2c_target_deinited(i2ctarget_i2c_target_obj_t *self) {
return self->sda_pin == NO_PIN;
}
void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) {
if (common_hal_i2ctarget_i2c_target_deinited(self)) {
return;
}
i2c_deinit(self->peripheral);
reset_pin_number(self->sda_pin);
reset_pin_number(self->scl_pin);
self->sda_pin = NO_PIN;
self->scl_pin = NO_PIN;
return;
}
static int i2c_peripheral_check_error(i2ctarget_i2c_target_obj_t *self, bool raise) {
return 0;
}
int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) {
if (!((self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) || (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS))) {
return 0;
}
*address = self->peripheral->hw->sar;
*is_read = !(self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS);
*is_restart = ((self->peripheral->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_RD_REQ_RESET) != 0);
common_hal_i2ctarget_i2c_target_ack(self, true);
return 1;
}
int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) {
if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) {
*data = (uint8_t)self->peripheral->hw->data_cmd;
return 1;
} else {
return 0;
}
}
int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) {
if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_TX_ABRT_BITS) {
self->peripheral->hw->clr_tx_abrt;
}
const size_t IC_TX_BUFFER_DEPTH = 16;
size_t space = IC_TX_BUFFER_DEPTH - self->peripheral->hw->txflr;
if (space > 0) {
self->peripheral->hw->data_cmd = data;
self->peripheral->hw->clr_rd_req;
return 1;
} else {
return 0;
}
}
void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) {
return;
}
void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) {
return;
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Mark Komus, Ken Stillson, im-redactd
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H
#define MICROPY_INCLUDED_RPI_COMMON_HAL_I2C_TARGET_H
#include "py/obj.h"
#include "common-hal/microcontroller/Pin.h"
#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h"
typedef struct {
mp_obj_base_t base;
uint8_t *addresses;
unsigned int num_addresses;
i2c_inst_t *peripheral;
uint8_t scl_pin;
uint8_t sda_pin;
} i2ctarget_i2c_target_obj_t;
#endif MICROPY_INCLUDED_RPI_COMMON_HAL_BUSIO_I2C_TARGET_H

View File

@ -0,0 +1 @@
// No i2ctarget module functions.

View File

@ -20,7 +20,7 @@ CIRCUITPY_ROTARYIO_SOFTENCODER = 1
# Things that need to be implemented. # Things that need to be implemented.
# Use PWM interally # Use PWM interally
CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CTARGET = 0 CIRCUITPY_I2CTARGET = 1
CIRCUITPY_NVM = 1 CIRCUITPY_NVM = 1
# Use PIO interally # Use PIO interally
CIRCUITPY_PULSEIO ?= 1 CIRCUITPY_PULSEIO ?= 1

View File

@ -31,6 +31,7 @@
#include "py/objstr.h" #include "py/objstr.h"
#include "py/stream.h" #include "py/stream.h"
#include "py/runtime.h" #include "py/runtime.h"
#include "py/unicode.h"
#include "supervisor/shared/translate/translate.h" #include "supervisor/shared/translate/translate.h"
// This file defines generic Python stream read/write methods which // This file defines generic Python stream read/write methods which
@ -43,6 +44,13 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in);
#define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes) #define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes)
static mp_obj_t mp_obj_new_str_from_vstr_check(const mp_obj_type_t *type, vstr_t *vstr) {
if (type == &mp_type_str && !utf8_check((void *)vstr->buf, vstr->len)) {
mp_raise_msg(&mp_type_UnicodeError, NULL);
}
return mp_obj_new_str_from_vstr(type, vstr);
}
// Returns error condition in *errcode, if non-zero, return value is number of bytes written // Returns error condition in *errcode, if non-zero, return value is number of bytes written
// before error condition occurred. If *errcode == 0, returns total bytes written (which will // before error condition occurred. If *errcode == 0, returns total bytes written (which will
// be equal to input size). // be equal to input size).
@ -201,8 +209,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl
} }
} }
} }
return mp_obj_new_str_from_vstr_check(&mp_type_str, &vstr);
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
} }
#endif #endif
@ -223,7 +230,7 @@ STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte fl
mp_raise_OSError(error); mp_raise_OSError(error);
} else { } else {
vstr.len = out_sz; vstr.len = out_sz;
return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr);
} }
} }
@ -364,7 +371,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
} }
vstr.len = total_size; vstr.len = total_size;
return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr);
} }
// Unbuffered, inefficient implementation of readline() for raw I/O files. // Unbuffered, inefficient implementation of readline() for raw I/O files.
@ -417,7 +424,7 @@ STATIC mp_obj_t stream_unbuffered_readline(size_t n_args, const mp_obj_t *args)
} }
} }
return mp_obj_new_str_from_vstr(STREAM_CONTENT_TYPE(stream_p), &vstr); return mp_obj_new_str_from_vstr_check(STREAM_CONTENT_TYPE(stream_p), &vstr);
} }
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline); MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline);

View File

@ -109,6 +109,11 @@ void port_wake_main_task(void);
// default weak implementation is provided that does nothing. // default weak implementation is provided that does nothing.
void port_wake_main_task_from_isr(void); void port_wake_main_task_from_isr(void);
// Some ports may use real RTOS tasks besides the background task framework of
// CircuitPython. Calling this will yield to other tasks and then return to the
// CircuitPython task when others are done.
void port_yield(void);
// Some ports need special handling just after completing boot.py execution. // Some ports need special handling just after completing boot.py execution.
// This function is called once while boot.py's VM is still valid, and // This function is called once while boot.py's VM is still valid, and
// then a second time after the VM is finalized. // then a second time after the VM is finalized.

View File

@ -47,11 +47,11 @@
#include "supervisor/shared/reload.h" #include "supervisor/shared/reload.h"
#include "supervisor/shared/bluetooth/file_transfer.h" #include "supervisor/shared/bluetooth/file_transfer.h"
#include "supervisor/shared/bluetooth/file_transfer_protocol.h" #include "supervisor/shared/bluetooth/file_transfer_protocol.h"
#include "supervisor/shared/workflow.h"
#include "supervisor/shared/tick.h" #include "supervisor/shared/tick.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include "py/mpstate.h" #include "py/mpstate.h"
#include "py/stackctrl.h"
STATIC bleio_service_obj_t supervisor_ble_service; STATIC bleio_service_obj_t supervisor_ble_service;
STATIC bleio_uuid_obj_t supervisor_ble_service_uuid; STATIC bleio_uuid_obj_t supervisor_ble_service_uuid;
@ -387,39 +387,6 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
return WRITE_DATA; return WRITE_DATA;
} }
STATIC FRESULT _delete_directory_contents(FATFS *fs, const TCHAR *path) {
FF_DIR dir;
FRESULT res = f_opendir(fs, &dir, path);
FILINFO file_info;
// Check the stack since we're putting paths on it.
if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) {
return FR_INT_ERR;
}
while (res == FR_OK) {
res = f_readdir(&dir, &file_info);
if (res != FR_OK || file_info.fname[0] == '\0') {
break;
}
size_t pathlen = strlen(path);
size_t fnlen = strlen(file_info.fname);
TCHAR full_path[pathlen + 1 + fnlen];
memcpy(full_path, path, pathlen);
full_path[pathlen] = '/';
size_t full_pathlen = pathlen + 1 + fnlen;
memcpy(full_path + pathlen + 1, file_info.fname, fnlen);
full_path[full_pathlen] = '\0';
if ((file_info.fattrib & AM_DIR) != 0) {
res = _delete_directory_contents(fs, full_path);
}
if (res != FR_OK) {
break;
}
res = f_unlink(fs, full_path);
}
f_closedir(&dir);
return res;
}
STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) { STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) {
const struct delete_command *command = (struct delete_command *)raw_buf; const struct delete_command *command = (struct delete_command *)raw_buf;
size_t header_size = sizeof(struct delete_command); size_t header_size = sizeof(struct delete_command);
@ -446,7 +413,7 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) {
FRESULT result = f_stat(fs, path, &file); FRESULT result = f_stat(fs, path, &file);
if (result == FR_OK) { if (result == FR_OK) {
if ((file.fattrib & AM_DIR) != 0) { if ((file.fattrib & AM_DIR) != 0) {
result = _delete_directory_contents(fs, path); result = supervisor_workflow_delete_directory_contents(fs, path);
} }
if (result == FR_OK) { if (result == FR_OK) {
result = f_unlink(fs, path); result = f_unlink(fs, path);
@ -503,7 +470,7 @@ STATIC uint8_t _process_mkdir(const uint8_t *raw_buf, size_t command_len) {
DWORD fattime; DWORD fattime;
response.truncated_time = truncate_time(command->modification_time, &fattime); response.truncated_time = truncate_time(command->modification_time, &fattime);
override_fattime(fattime); override_fattime(fattime);
FRESULT result = f_mkdir(fs, path); FRESULT result = supervisor_workflow_mkdir_parents(fs, path);
override_fattime(0); override_fattime(0);
#if CIRCUITPY_USB_MSC #if CIRCUITPY_USB_MSC
usb_msc_unlock(); usb_msc_unlock();

View File

@ -31,3 +31,6 @@ MP_WEAK void port_wake_main_task(void) {
MP_WEAK void port_wake_main_task_from_isr(void) { MP_WEAK void port_wake_main_task_from_isr(void) {
} }
MP_WEAK void port_yield(void) {
}

View File

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="https://code.circuitpython.org/assets/images/favicon.ico" type="image/x-icon" />
<title>Online Code Editor</title>
</head>
<body>
<script type="module" src="https://code.circuitpython.org/assets/js/device.js"></script>
<p>Uh oh! It looks like you may be offline. You can go to the <a href="/fs/">file browser</a> if you'd like to work with files without connecting to the internet.</p>
</body>
</html>

View File

@ -10,13 +10,15 @@
<body> <body>
<h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;<span id="path"></span></h1> <h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;<span id="path"></span></h1>
<div id="usbwarning" style="display: none;"> USB is using the storage. Only allowing reads. See <a href="https://learn.adafruit.com/circuitpython-essentials/circuitpython-storage">the CircuitPython Essentials: Storage guide</a> for details.</div> <div id="usbwarning" style="display: none;"> USB is using the storage. Only allowing reads. See <a href="https://learn.adafruit.com/circuitpython-essentials/circuitpython-storage">the CircuitPython Essentials: Storage guide</a> for details.</div>
<template id="row"><tr><td></td><td></td><td><a></a></td><td></td><td><button class="delete">🗑️</button></td><td><a class="edit_link" href="">Edit</a></td></tr></template> <template id="row"><tr><td></td><td></td><td><a class="path"></a></td><td class="modtime"></td><td><button class="rename">✏️ Rename</button></td><td><button class="delete">🗑️ Delete</button></td><td><a class="edit_link" href=""><button>📝 Edit</button></a></td></tr></template>
<table> <table>
<thead><tr><th>Type</th><th>Size</th><th>Path</th><th>Modified</th><th></th></tr></thead> <thead><tr><th>Type</th><th>Size</th><th>Path</th><th>Modified</th><th colspan="3"></th></tr></thead>
<tbody></tbody> <tbody></tbody>
</table> </table>
<hr> <hr>
<input type="file" id="files" multiple><button type="submit" id="upload">Upload</button> <label>📄 <input type="file" id="files" multiple></label>
<label for="dirs">📁 <input type="file" id="dirs" multiple webkitdirectory></label>
<label>Upload progress:<progress value="0"></progress></label>
<hr> <hr>
+📁&nbsp;<input type="text" id="name"><button type="submit" id="mkdir">Create Directory</button> +📁&nbsp;<input type="text" id="name"><button type="submit" id="mkdir">Create Directory</button>
</body></html> </body></html>

View File

@ -1,20 +1,27 @@
let new_directory_name = document.getElementById("name"); let new_directory_name = document.getElementById("name");
let files = document.getElementById("files"); let files = document.getElementById("files");
let dirs = document.getElementById("dirs");
var url_base = window.location; var url_base = window.location;
var current_path; var current_path;
var editable = undefined; var editable = undefined;
async function refresh_list() { function compareValues(a, b) {
function compareValues(a, b) {
if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) { if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) {
return 0; return 0;
} else if (a.directory != b.directory) {
return a.directory < b.directory ? 1 : -1;
} else { } else {
return a.directory.toString().substring(3,4)+a.name.toLowerCase() < b.directory.toString().substring(3,4)+b.name.toLowerCase() ? -1 : 1; return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
}
} }
}
function set_upload_enabled(enabled) {
files.disabled = !enabled;
dirs.disabled = !enabled;
}
async function refresh_list() {
current_path = window.location.hash.substr(1); current_path = window.location.hash.substr(1);
if (current_path == "") { if (current_path == "") {
current_path = "/"; current_path = "/";
@ -45,14 +52,14 @@ async function refresh_list() {
); );
editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE"); editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE");
new_directory_name.disabled = !editable; new_directory_name.disabled = !editable;
files.disabled = !editable; set_upload_enabled(editable);
if (!editable) { if (!editable) {
let usbwarning = document.querySelector("#usbwarning"); let usbwarning = document.querySelector("#usbwarning");
usbwarning.style.display = "block"; usbwarning.style.display = "block";
} }
} }
if (window.location.path != "/fs/") { if (current_path != "/") {
var clone = template.content.cloneNode(true); var clone = template.content.cloneNode(true);
var td = clone.querySelectorAll("td"); var td = clone.querySelectorAll("td");
td[0].textContent = "📁"; td[0].textContent = "📁";
@ -62,6 +69,8 @@ async function refresh_list() {
path.textContent = ".."; path.textContent = "..";
// Remove the delete button // Remove the delete button
td[4].replaceChildren(); td[4].replaceChildren();
td[5].replaceChildren();
td[6].replaceChildren();
new_children.push(clone); new_children.push(clone);
} }
@ -82,31 +91,46 @@ async function refresh_list() {
file_path = api_url; file_path = api_url;
} }
var text_file = false;
if (f.directory) { if (f.directory) {
icon = "📁"; icon = "📁";
} else if(f.name.endsWith(".txt") || } else if(f.name.endsWith(".txt") ||
f.name.endsWith(".env") ||
f.name.endsWith(".py") || f.name.endsWith(".py") ||
f.name.endsWith(".js") || f.name.endsWith(".js") ||
f.name.endsWith(".json")) { f.name.endsWith(".json")) {
icon = "📄"; icon = "📄";
text_file = true;
} else if (f.name.endsWith(".html")) { } else if (f.name.endsWith(".html")) {
icon = "🌐"; icon = "🌐";
text_file = true;
} }
td[0].textContent = icon; td[0].textContent = icon;
td[1].textContent = f.file_size; td[1].textContent = f.file_size;
var path = clone.querySelector("a"); var path = clone.querySelector("a.path");
path.href = file_path; path.href = file_path;
path.textContent = f.name; path.textContent = f.name;
td[3].textContent = (new Date(f.modified_ns / 1000000)).toLocaleString(); let modtime = clone.querySelector("td.modtime");
modtime.textContent = (new Date(f.modified_ns / 1000000)).toLocaleString();
var delete_button = clone.querySelector("button.delete"); var delete_button = clone.querySelector("button.delete");
delete_button.value = api_url; delete_button.value = api_url;
delete_button.disabled = !editable; delete_button.disabled = !editable;
delete_button.onclick = del; delete_button.onclick = del;
if (editable && !f.directory) {
edit_url = new URL(edit_url, url_base); var rename_button = clone.querySelector("button.rename");
rename_button.value = api_url;
rename_button.disabled = !editable;
rename_button.onclick = rename;
let edit_link = clone.querySelector(".edit_link"); let edit_link = clone.querySelector(".edit_link");
if (text_file && editable && !f.directory) {
edit_url = new URL(edit_url, url_base);
edit_link.href = edit_url edit_link.href = edit_url
} else if (f.directory) {
edit_link.style = "display: none;";
} else {
edit_link.querySelector("button").disabled = true;
} }
new_children.push(clone); new_children.push(clone);
@ -148,8 +172,25 @@ async function mkdir(e) {
} }
async function upload(e) { async function upload(e) {
for (const file of files.files) { set_upload_enabled(false);
let file_path = new URL("/fs" + current_path + file.name, url_base); let progress = document.querySelector("progress");
let made_dirs = new Set();
progress.max = files.files.length + dirs.files.length;
progress.value = 0;
for (const file of [...files.files, ...dirs.files]) {
let file_name = file.name;
if (file.webkitRelativePath) {
file_name = file.webkitRelativePath;
let components = file_name.split("/");
components.pop();
let parent_dir = components.join("/");
if (!made_dirs.has(parent_dir)) {
new_directory_name.value = parent_dir;
await mkdir(null);
made_dirs.add(parent_dir);
}
}
let file_path = new URL("/fs" + current_path + file_name, url_base);
const response = await fetch(file_path, const response = await fetch(file_path,
{ {
method: "PUT", method: "PUT",
@ -163,9 +204,12 @@ async function upload(e) {
if (response.ok) { if (response.ok) {
refresh_list(); refresh_list();
} }
progress.value += 1;
} }
files.value = ""; files.value = "";
upload_button.disabled = true; dirs.value = "";
progress.value = 0;
set_upload_enabled(true);
} }
async function del(e) { async function del(e) {
@ -188,19 +232,33 @@ async function del(e) {
} }
} }
async function rename(e) {
let fn = new URL(e.target.value);
var new_fn = prompt("Rename to ", fn.pathname.substr(3));
if (new_fn === null) {
return;
}
let new_uri = new URL("/fs" + new_fn, fn);
const response = await fetch(e.target.value,
{
method: "MOVE",
headers: {
'X-Destination': new_uri.pathname,
},
}
)
if (response.ok) {
refresh_list();
}
}
find_devices(); find_devices();
let mkdir_button = document.getElementById("mkdir"); let mkdir_button = document.getElementById("mkdir");
mkdir_button.onclick = mkdir; mkdir_button.onclick = mkdir;
let upload_button = document.getElementById("upload"); files.onchange = upload;
upload_button.onclick = upload; dirs.onchange = upload;
upload_button.disabled = files.files.length == 0;
files.onchange = () => {
upload_button.disabled = files.files.length == 0;
}
mkdir_button.disabled = new_directory_name.value.length == 0; mkdir_button.disabled = new_directory_name.value.length == 0;

View File

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Code Edit</title> <title>Offline Code Edit</title>
<link rel="stylesheet" href="http://circuitpython.org/assets/css/webworkflow-8.css"> <link rel="stylesheet" href="http://circuitpython.org/assets/css/webworkflow-8.css">
<link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/style.css">
</head> </head>

View File

@ -17,3 +17,7 @@ body {
margin: 0; margin: 0;
font-size: 0.7em; font-size: 0.7em;
} }
:disabled {
filter: saturate(0%);
}

View File

@ -1,7 +1,7 @@
var url_base = window.location; var url_base = window.location;
var current_path; var current_path;
var mdns_works = window.location.hostname.endsWith(".local"); var mdns_works = url_base.hostname.endsWith(".local");
async function find_devices() { async function find_devices() {
var version_response = await fetch("/cp/version.json"); var version_response = await fetch("/cp/version.json");

View File

@ -37,10 +37,12 @@
#include "shared/timeutils/timeutils.h" #include "shared/timeutils/timeutils.h"
#include "supervisor/fatfs_port.h" #include "supervisor/fatfs_port.h"
#include "supervisor/filesystem.h" #include "supervisor/filesystem.h"
#include "supervisor/port.h"
#include "supervisor/shared/reload.h" #include "supervisor/shared/reload.h"
#include "supervisor/shared/translate/translate.h" #include "supervisor/shared/translate/translate.h"
#include "supervisor/shared/web_workflow/web_workflow.h" #include "supervisor/shared/web_workflow/web_workflow.h"
#include "supervisor/shared/web_workflow/websocket.h" #include "supervisor/shared/web_workflow/websocket.h"
#include "supervisor/shared/workflow.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/__init__.h"
@ -77,8 +79,9 @@ typedef struct {
enum request_state state; enum request_state state;
char method[8]; char method[8];
char path[256]; char path[256];
char destination[256];
char header_key[64]; char header_key[64];
char header_value[64]; char header_value[256];
// We store the origin so we can reply back with it. // We store the origin so we can reply back with it.
char origin[64]; char origin[64];
size_t content_length; size_t content_length;
@ -323,22 +326,31 @@ void supervisor_start_web_workflow(void) {
#endif #endif
} }
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) { void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
int total_sent = 0;
int sent = -EAGAIN; int sent = -EAGAIN;
while (sent == -EAGAIN && common_hal_socketpool_socket_get_connected(socket)) { while ((sent == -EAGAIN || (sent > 0 && total_sent < len)) &&
sent = socketpool_socket_send(socket, buf, len); common_hal_socketpool_socket_get_connected(socket)) {
sent = socketpool_socket_send(socket, buf + total_sent, len - total_sent);
if (sent > 0) {
total_sent += sent;
if (total_sent < len) {
// Yield so that network code can run.
port_yield();
} }
if (sent < len) { }
}
if (total_sent < len) {
ESP_LOGE(TAG, "short send %d %d", sent, len); ESP_LOGE(TAG, "short send %d %d", sent, len);
} }
} }
STATIC void _print_raw(void *env, const char *str, size_t len) { STATIC void _print_raw(void *env, const char *str, size_t len) {
_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, (size_t)len); web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, (size_t)len);
} }
static void _send_str(socketpool_socket_obj_t *socket, const char *str) { static void _send_str(socketpool_socket_obj_t *socket, const char *str) {
_send_raw(socket, (const uint8_t *)str, strlen(str)); web_workflow_send_raw(socket, (const uint8_t *)str, strlen(str));
} }
// The last argument must be NULL! Otherwise, it won't stop. // The last argument must be NULL! Otherwise, it won't stop.
@ -357,15 +369,15 @@ static void _send_strs(socketpool_socket_obj_t *socket, ...) {
static void _send_chunk(socketpool_socket_obj_t *socket, const char *chunk) { static void _send_chunk(socketpool_socket_obj_t *socket, const char *chunk) {
mp_print_t _socket_print = {socket, _print_raw}; mp_print_t _socket_print = {socket, _print_raw};
mp_printf(&_socket_print, "%X\r\n", strlen(chunk)); mp_printf(&_socket_print, "%X\r\n", strlen(chunk));
_send_raw(socket, (const uint8_t *)chunk, strlen(chunk)); web_workflow_send_raw(socket, (const uint8_t *)chunk, strlen(chunk));
_send_raw(socket, (const uint8_t *)"\r\n", 2); web_workflow_send_raw(socket, (const uint8_t *)"\r\n", 2);
} }
STATIC void _print_chunk(void *env, const char *str, size_t len) { STATIC void _print_chunk(void *env, const char *str, size_t len) {
mp_print_t _socket_print = {env, _print_raw}; mp_print_t _socket_print = {env, _print_raw};
mp_printf(&_socket_print, "%X\r\n", len); mp_printf(&_socket_print, "%X\r\n", len);
_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, len); web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)str, len);
_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)"\r\n", 2); web_workflow_send_raw((socketpool_socket_obj_t *)env, (const uint8_t *)"\r\n", 2);
} }
// A bit of a misnomer because it sends all arguments as one chunk. // A bit of a misnomer because it sends all arguments as one chunk.
@ -543,6 +555,15 @@ static void _reply_conflict(socketpool_socket_obj_t *socket, _request *request)
_send_str(socket, "\r\nUSB storage active."); _send_str(socket, "\r\nUSB storage active.");
} }
static void _reply_precondition_failed(socketpool_socket_obj_t *socket, _request *request) {
_send_strs(socket,
"HTTP/1.1 412 Precondition Failed\r\n",
"Content-Length: 0\r\n", NULL);
_cors_header(socket, request);
_send_str(socket, "\r\n");
}
static void _reply_payload_too_large(socketpool_socket_obj_t *socket, _request *request) { static void _reply_payload_too_large(socketpool_socket_obj_t *socket, _request *request) {
_send_strs(socket, _send_strs(socket,
"HTTP/1.1 413 Payload Too Large\r\n", "HTTP/1.1 413 Payload Too Large\r\n",
@ -753,40 +774,6 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request *
_send_chunk(socket, ""); _send_chunk(socket, "");
} }
// Copied from ble file_transfer.c. We should share it.
STATIC FRESULT _delete_directory_contents(FATFS *fs, const TCHAR *path) {
FF_DIR dir;
FRESULT res = f_opendir(fs, &dir, path);
FILINFO file_info;
// Check the stack since we're putting paths on it.
if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) {
return FR_INT_ERR;
}
while (res == FR_OK) {
res = f_readdir(&dir, &file_info);
if (res != FR_OK || file_info.fname[0] == '\0') {
break;
}
size_t pathlen = strlen(path);
size_t fnlen = strlen(file_info.fname);
TCHAR full_path[pathlen + 1 + fnlen];
memcpy(full_path, path, pathlen);
full_path[pathlen] = '/';
size_t full_pathlen = pathlen + 1 + fnlen;
memcpy(full_path + pathlen + 1, file_info.fname, fnlen);
full_path[full_pathlen] = '\0';
if ((file_info.fattrib & AM_DIR) != 0) {
res = _delete_directory_contents(fs, full_path);
}
if (res != FR_OK) {
break;
}
res = f_unlink(fs, full_path);
}
f_closedir(&dir);
return res;
}
// FATFS has a two second timestamp resolution but the BLE API allows for nanosecond resolution. // 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 // This function truncates the time the time to a resolution storable by FATFS and fills in the
// FATFS encoded version into fattime. // FATFS encoded version into fattime.
@ -916,6 +903,7 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req
#define STATIC_FILE(filename) extern uint32_t filename##_length; extern uint8_t filename[]; extern const char *filename##_content_type; #define STATIC_FILE(filename) extern uint32_t filename##_length; extern uint8_t filename[]; extern const char *filename##_content_type;
STATIC_FILE(code_html);
STATIC_FILE(directory_html); STATIC_FILE(directory_html);
STATIC_FILE(directory_js); STATIC_FILE(directory_js);
STATIC_FILE(welcome_html); STATIC_FILE(welcome_html);
@ -938,7 +926,7 @@ static void _reply_static(socketpool_socket_obj_t *socket, _request *request, co
"Content-Length: ", encoded_len, "\r\n", "Content-Length: ", encoded_len, "\r\n",
"Content-Type: ", content_type, "\r\n", "Content-Type: ", content_type, "\r\n",
"\r\n", NULL); "\r\n", NULL);
_send_raw(socket, response, response_len); web_workflow_send_raw(socket, response, response_len);
} }
#define _REPLY_STATIC(socket, request, filename) _reply_static(socket, request, filename, filename##_length, filename##_content_type) #define _REPLY_STATIC(socket, request, filename) _reply_static(socket, request, filename, filename##_length, filename##_content_type)
@ -976,6 +964,28 @@ static uint8_t _hex2nibble(char h) {
return h - 'a' + 0xa; return h - 'a' + 0xa;
} }
// Decode percent encoding in place. Only do this once on a string!
static void _decode_percents(char *str) {
size_t o = 0;
size_t i = 0;
size_t startlen = strlen(str);
while (i < startlen) {
if (str[i] == '%') {
str[o] = _hex2nibble(str[i + 1]) << 4 | _hex2nibble(str[i + 2]);
i += 3;
} else {
if (i != o) {
str[o] = str[i];
}
i += 1;
}
o += 1;
}
if (o < i) {
str[o] = '\0';
}
}
static bool _reply(socketpool_socket_obj_t *socket, _request *request) { static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
if (request->redirect) { if (request->redirect) {
_reply_redirect(socket, request, request->path); _reply_redirect(socket, request, request->path);
@ -996,23 +1006,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
// Decode any percent encoded bytes so that we're left with UTF-8. // Decode any percent encoded bytes so that we're left with UTF-8.
// We only do this on /fs/ paths and after redirect so that any // We only do this on /fs/ paths and after redirect so that any
// path echoing we do stays encoded. // path echoing we do stays encoded.
size_t o = 0; _decode_percents(request->path);
size_t i = 0;
while (i < strlen(request->path)) {
if (request->path[i] == '%') {
request->path[o] = _hex2nibble(request->path[i + 1]) << 4 | _hex2nibble(request->path[i + 2]);
i += 3;
} else {
if (i != o) {
request->path[o] = request->path[i];
}
i += 1;
}
o += 1;
}
if (o < i) {
request->path[o] = '\0';
}
char *path = request->path + 3; char *path = request->path + 3;
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
FATFS *fs = filesystem_circuitpy(); FATFS *fs = filesystem_circuitpy();
@ -1037,7 +1032,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
FRESULT result = f_stat(fs, path, &file); FRESULT result = f_stat(fs, path, &file);
if (result == FR_OK) { if (result == FR_OK) {
if ((file.fattrib & AM_DIR) != 0) { if ((file.fattrib & AM_DIR) != 0) {
result = _delete_directory_contents(fs, path); result = supervisor_workflow_delete_directory_contents(fs, path);
} }
if (result == FR_OK) { if (result == FR_OK) {
result = f_unlink(fs, path); result = f_unlink(fs, path);
@ -1056,6 +1051,34 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
_reply_no_content(socket, request); _reply_no_content(socket, request);
return true; return true;
} }
} else if (strcasecmp(request->method, "MOVE") == 0) {
if (_usb_active()) {
_reply_conflict(socket, request);
return false;
}
_decode_percents(request->destination);
char *destination = request->destination + 3;
size_t destinationlen = strlen(destination);
if (destination[destinationlen - 1] == '/' && destinationlen > 1) {
destination[destinationlen - 1] = '\0';
}
FRESULT result = f_rename(fs, path, destination);
#if CIRCUITPY_USB_MSC
usb_msc_unlock();
#endif
if (result == FR_EXIST) { // File exists and won't be overwritten.
_reply_precondition_failed(socket, request);
} else if (result == FR_NO_PATH || result == FR_NO_FILE) { // Missing higher directories or target file.
_reply_missing(socket, request);
} else if (result != FR_OK) {
ESP_LOGE(TAG, "move error %d %s", result, path);
_reply_server_error(socket, request);
} else {
_reply_created(socket, request);
return true;
}
} else if (directory) { } else if (directory) {
if (strcasecmp(request->method, "GET") == 0) { if (strcasecmp(request->method, "GET") == 0) {
FF_DIR dir; FF_DIR dir;
@ -1088,7 +1111,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
truncate_time(request->timestamp_ms * 1000000, &fattime); truncate_time(request->timestamp_ms * 1000000, &fattime);
override_fattime(fattime); override_fattime(fattime);
} }
FRESULT result = f_mkdir(fs, path); FRESULT result = supervisor_workflow_mkdir_parents(fs, path);
override_fattime(0); override_fattime(0);
#if CIRCUITPY_USB_MSC #if CIRCUITPY_USB_MSC
usb_msc_unlock(); usb_msc_unlock();
@ -1133,6 +1156,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
} else { } else {
_REPLY_STATIC(socket, request, edit_html); _REPLY_STATIC(socket, request, edit_html);
} }
} else if (strcmp(request->path, "/code/") == 0) {
_REPLY_STATIC(socket, request, code_html);
} else if (strncmp(request->path, "/cp/", 4) == 0) { } else if (strncmp(request->path, "/cp/", 4) == 0) {
const char *path = request->path + 3; const char *path = request->path + 3;
if (strcasecmp(request->method, "OPTIONS") == 0) { if (strcasecmp(request->method, "OPTIONS") == 0) {
@ -1308,6 +1333,8 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
} else if (strcasecmp(request->header_key, "Sec-WebSocket-Key") == 0 && } else if (strcasecmp(request->header_key, "Sec-WebSocket-Key") == 0 &&
strlen(request->header_value) == 24) { strlen(request->header_value) == 24) {
strcpy(request->websocket_key, request->header_value); strcpy(request->websocket_key, request->header_value);
} else if (strcasecmp(request->header_key, "X-Destination") == 0) {
strcpy(request->destination, request->header_value);
} }
ESP_LOGI(TAG, "Header %s %s", request->header_key, request->header_value); ESP_LOGI(TAG, "Header %s %s", request->header_key, request->header_value);
} else if (request->offset > sizeof(request->header_value) - 1) { } else if (request->offset > sizeof(request->header_value) - 1) {

View File

@ -28,6 +28,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "shared-bindings/socketpool/Socket.h"
// This background function should be called repeatedly. It cannot be done based // This background function should be called repeatedly. It cannot be done based
// on events. // on events.
void supervisor_web_workflow_background(void); void supervisor_web_workflow_background(void);
@ -35,3 +37,6 @@ bool supervisor_web_workflow_status_dirty(void);
void supervisor_web_workflow_status(void); void supervisor_web_workflow_status(void);
void supervisor_start_web_workflow(void); void supervisor_start_web_workflow(void);
void supervisor_stop_web_workflow(void); void supervisor_stop_web_workflow(void);
// To share with websocket.
void web_workflow_send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len);

View File

@ -30,6 +30,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "shared/runtime/interrupt_char.h" #include "shared/runtime/interrupt_char.h"
#include "supervisor/shared/title_bar.h" #include "supervisor/shared/title_bar.h"
#include "supervisor/shared/web_workflow/web_workflow.h"
// TODO: Remove ESP specific stuff. For now, it is useful as we refine the server. // TODO: Remove ESP specific stuff. For now, it is useful as we refine the server.
#include "esp_log.h" #include "esp_log.h"
@ -77,7 +78,7 @@ void websocket_handoff(socketpool_socket_obj_t *socket) {
} }
bool websocket_connected(void) { bool websocket_connected(void) {
return !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket); return _incoming_ringbuf.size > 0 && !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket);
} }
static bool _read_byte(uint8_t *c) { static bool _read_byte(uint8_t *c) {
@ -91,16 +92,6 @@ static bool _read_byte(uint8_t *c) {
return true; return true;
} }
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
int sent = -EAGAIN;
while (sent == -EAGAIN) {
sent = socketpool_socket_send(socket, buf, len);
}
if (sent < len) {
ESP_LOGE(TAG, "short send on %d err %d len %d", socket->num, sent, len);
}
}
static void _read_next_frame_header(void) { static void _read_next_frame_header(void) {
uint8_t h; uint8_t h;
if (cp_serial.frame_index == 0 && _read_byte(&h)) { if (cp_serial.frame_index == 0 && _read_byte(&h)) {
@ -159,14 +150,14 @@ static void _read_next_frame_header(void) {
ESP_LOGE(TAG, "CLOSE or PING has long payload"); ESP_LOGE(TAG, "CLOSE or PING has long payload");
} }
frame_header[1] = cp_serial.payload_remaining; frame_header[1] = cp_serial.payload_remaining;
_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2); web_workflow_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2);
} }
if (cp_serial.payload_remaining > 0 && _read_byte(&h)) { if (cp_serial.payload_remaining > 0 && _read_byte(&h)) {
// Send the payload back to the client. // Send the payload back to the client.
cp_serial.frame_index++; cp_serial.frame_index++;
cp_serial.payload_remaining--; cp_serial.payload_remaining--;
_send_raw(&cp_serial.socket, &h, 1); web_workflow_send_raw(&cp_serial.socket, &h, 1);
} }
if (cp_serial.payload_remaining == 0) { if (cp_serial.payload_remaining == 0) {
@ -231,23 +222,23 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) {
payload_len = 127; payload_len = 127;
} }
frame_header[1] = payload_len; frame_header[1] = payload_len;
_send_raw(&ws->socket, (const uint8_t *)frame_header, 2); web_workflow_send_raw(&ws->socket, (const uint8_t *)frame_header, 2);
uint8_t extended_len[4]; uint8_t extended_len[4];
if (payload_len == 126) { if (payload_len == 126) {
extended_len[0] = (len >> 8) & 0xff; extended_len[0] = (len >> 8) & 0xff;
extended_len[1] = len & 0xff; extended_len[1] = len & 0xff;
_send_raw(&ws->socket, extended_len, 2); web_workflow_send_raw(&ws->socket, extended_len, 2);
} else if (payload_len == 127) { } else if (payload_len == 127) {
uint32_t zero = 0; uint32_t zero = 0;
// 64 bits where top four bytes are zero. // 64 bits where top four bytes are zero.
_send_raw(&ws->socket, (const uint8_t *)&zero, 4); web_workflow_send_raw(&ws->socket, (const uint8_t *)&zero, 4);
extended_len[0] = (len >> 24) & 0xff; extended_len[0] = (len >> 24) & 0xff;
extended_len[1] = (len >> 16) & 0xff; extended_len[1] = (len >> 16) & 0xff;
extended_len[2] = (len >> 8) & 0xff; extended_len[2] = (len >> 8) & 0xff;
extended_len[3] = len & 0xff; extended_len[3] = len & 0xff;
_send_raw(&ws->socket, extended_len, 4); web_workflow_send_raw(&ws->socket, extended_len, 4);
} }
_send_raw(&ws->socket, (const uint8_t *)text, len); web_workflow_send_raw(&ws->socket, (const uint8_t *)text, len);
} }
void websocket_write(const char *text, size_t len) { void websocket_write(const char *text, size_t len) {
@ -255,6 +246,9 @@ void websocket_write(const char *text, size_t len) {
} }
void websocket_background(void) { void websocket_background(void) {
if (!websocket_connected()) {
return;
}
uint8_t c; uint8_t c;
while (ringbuf_num_empty(&_incoming_ringbuf) > 0 && while (ringbuf_num_empty(&_incoming_ringbuf) > 0 &&
_read_next_payload_byte(&c)) { _read_next_payload_byte(&c)) {

View File

@ -26,6 +26,8 @@
#include <stdbool.h> #include <stdbool.h>
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "py/mpstate.h"
#include "py/stackctrl.h"
#include "supervisor/background_callback.h" #include "supervisor/background_callback.h"
#include "supervisor/workflow.h" #include "supervisor/workflow.h"
#include "supervisor/serial.h" #include "supervisor/serial.h"
@ -46,6 +48,8 @@
#endif #endif
static background_callback_t workflow_background_cb; static background_callback_t workflow_background_cb;
static bool workflow_started = false;
static void workflow_background(void *data) { static void workflow_background(void *data) {
#if CIRCUITPY_WEB_WORKFLOW #if CIRCUITPY_WEB_WORKFLOW
supervisor_web_workflow_background(); supervisor_web_workflow_background();
@ -68,6 +72,9 @@ void supervisor_workflow_reset(void) {
} }
void supervisor_workflow_request_background(void) { void supervisor_workflow_request_background(void) {
if (!workflow_started) {
return;
}
background_callback_add_core(&workflow_background_cb); background_callback_add_core(&workflow_background_cb);
} }
@ -114,4 +121,63 @@ void supervisor_workflow_start(void) {
#if CIRCUITPY_WEB_WORKFLOW #if CIRCUITPY_WEB_WORKFLOW
supervisor_start_web_workflow(); supervisor_start_web_workflow();
#endif #endif
workflow_started = true;
}
FRESULT supervisor_workflow_mkdir_parents(FATFS *fs, char *path) {
FRESULT result = FR_OK;
// Make parent directories.
for (size_t j = 1; j < strlen(path); j++) {
if (path[j] == '/') {
path[j] = '\0';
result = f_mkdir(fs, path);
path[j] = '/';
if (result != FR_OK && result != FR_EXIST) {
return result;
}
}
}
// Make the target directory.
return f_mkdir(fs, path);
}
FRESULT supervisor_workflow_delete_directory_contents(FATFS *fs, const TCHAR *path) {
FF_DIR dir;
FILINFO file_info;
// Check the stack since we're putting paths on it.
if (mp_stack_usage() >= MP_STATE_THREAD(stack_limit)) {
return FR_INT_ERR;
}
FRESULT res = FR_OK;
while (res == FR_OK) {
res = f_opendir(fs, &dir, path);
if (res != FR_OK) {
break;
}
res = f_readdir(&dir, &file_info);
// We close and reopen the directory every time since we're deleting
// entries and it may invalidate the directory handle.
f_closedir(&dir);
if (res != FR_OK || file_info.fname[0] == '\0') {
break;
}
size_t pathlen = strlen(path);
size_t fnlen = strlen(file_info.fname);
TCHAR full_path[pathlen + 1 + fnlen];
memcpy(full_path, path, pathlen);
full_path[pathlen] = '/';
size_t full_pathlen = pathlen + 1 + fnlen;
memcpy(full_path + pathlen + 1, file_info.fname, fnlen);
full_path[full_pathlen] = '\0';
if ((file_info.fattrib & AM_DIR) != 0) {
res = supervisor_workflow_delete_directory_contents(fs, full_path);
}
if (res != FR_OK) {
break;
}
res = f_unlink(fs, full_path);
}
f_closedir(&dir);
return res;
} }

View File

@ -26,4 +26,10 @@
#pragma once #pragma once
#include "lib/oofatfs/ff.h"
extern bool supervisor_workflow_connecting(void); extern bool supervisor_workflow_connecting(void);
// File system helpers for workflow code.
FRESULT supervisor_workflow_mkdir_parents(FATFS *fs, char *path);
FRESULT supervisor_workflow_delete_directory_contents(FATFS *fs, const TCHAR *path);

View File

@ -5,7 +5,7 @@ except:
raise SystemExit raise SystemExit
loc = __file__.rsplit("/", 1)[0] loc = __file__.rsplit("/", 1)[0]
with open(f"{loc}/data/qr.pgm") as f: with open(f"{loc}/data/qr.pgm", "rb") as f:
content = f.read()[-320 * 240 :] content = f.read()[-320 * 240 :]
decoder = qrio.QRDecoder(320, 240) decoder = qrio.QRDecoder(320, 240)