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/
```
##### 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
Deletes the directory and all of its contents.
@ -214,7 +232,7 @@ Deletes the directory and all of its contents.
Example:
```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
Deletes the file.
@ -283,7 +320,7 @@ Deletes the file.
Example:
```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/`

View File

@ -6,14 +6,14 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2022-05-20 19:25+0000\n"
"Last-Translator: Fabian Affolter <mail@fabian-affolter.ch>\n"
"PO-Revision-Date: 2022-08-14 12:14+0000\n"
"Last-Translator: Can Kocyigit <cank3698@googlemail.com>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.13-dev\n"
"X-Generator: Weblate 4.14-dev\n"
#: main.c
msgid ""
@ -82,7 +82,7 @@ msgstr ""
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
msgstr "%q"
#: shared-bindings/microcontroller/Pin.c
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
msgid "%q and %q must be different"
msgstr ""
msgstr "%q und %q müssen unterschiedlich sein"
#: shared-bindings/microcontroller/Pin.c
msgid "%q contains duplicate pins"
@ -114,11 +114,11 @@ msgstr "%q Indizes müssen Integer sein, nicht %s"
#: shared-module/bitbangio/SPI.c
msgid "%q init failed"
msgstr ""
msgstr "%q Initialisierung ist gescheitert"
#: py/argcheck.c
msgid "%q length must be %d"
msgstr ""
msgstr "%q länge muss %d betragen"
#: py/argcheck.c
msgid "%q length must be %d-%d"
@ -126,11 +126,11 @@ msgstr "%q Länge muss %d-%d sein"
#: py/argcheck.c
msgid "%q length must be <= %d"
msgstr ""
msgstr "%q länge muss kleiner oder gleich %d sein"
#: py/argcheck.c
msgid "%q length must be >= %d"
msgstr ""
msgstr "%q länge muss größer oder gleich %d sein"
#: shared-bindings/busio/I2C.c
msgid "%q length must be >= 1"
@ -138,7 +138,7 @@ msgstr "%q Länge muss >= 1 sein"
#: py/argcheck.c
msgid "%q must be %d"
msgstr ""
msgstr "%q muss %d entsprechen"
#: py/argcheck.c
msgid "%q must be %d-%d"
@ -170,7 +170,7 @@ msgstr "%q muss ein String sein"
#: py/argcheck.c
msgid "%q must be an int"
msgstr ""
msgstr "%q muss vom Typ Integer sein"
#: py/argcheck.c
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
msgid "%q=%q"
msgstr ""
msgstr "%q=%q"
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
#, c-format
@ -413,7 +413,7 @@ msgstr "Alle I2C-Peripheriegeräte sind in Benutzung"
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c
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/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
msgid "Camera init"
msgstr ""
msgstr "Kamera Initialiserung"
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
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/mimxrt10xx/common-hal/microcontroller/__init__.c
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
msgid "Cannot set socket options"
@ -757,7 +757,7 @@ msgstr "Slice kann keine sub-klasse sein"
#: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins"
msgstr ""
msgstr "Kann nicht ohne MISO und MOSI Pins transferieren"
#: shared-bindings/pwmio/PWMOut.c
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"
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c
#, fuzzy
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
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
msgid "Done"
msgstr ""
msgstr "Fertig"
#: shared-bindings/digitalio/DigitalInOut.c
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
msgid "Failed to allocate %q buffer"
msgstr ""
msgstr "Allokieren des %q Buffers ist fehlgeschlagen"
#: ports/espressif/common-hal/wifi/__init__.c
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
msgid "GNSS init"
msgstr ""
msgstr "GNSS Initialisierung"
#: ports/espressif/common-hal/espidf/__init__.c ports/espressif/esp_error.c
msgid "Generic Failure"
@ -1080,7 +1081,7 @@ msgstr "Lese/Schreibe-operation an geschlossener Datei"
#: ports/stm/common-hal/busio/I2C.c
msgid "I2C init error"
msgstr ""
msgstr "I2C Initialisierungsfehler"
#: ports/raspberrypi/common-hal/busio/I2C.c
msgid "I2C peripheral in use"
@ -1195,7 +1196,7 @@ msgstr "Interner Fehler #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
msgstr "Der Interne WatchDog Timer ist abgelaufen."
#: py/argcheck.c
msgid "Invalid %q"
@ -1278,11 +1279,11 @@ msgstr "LHS des Schlüsselwortarguments muss eine id sein"
#: shared-module/displayio/Group.c
msgid "Layer already in a group"
msgstr ""
msgstr "Ebene ist bereits in der Gruppe"
#: shared-module/displayio/Group.c
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
msgid "MAC address was invalid"
@ -1317,7 +1318,7 @@ msgstr "Fehlender MISO- oder MOSI-Pin"
#: ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI pin"
msgstr ""
msgstr "MISO oder MOSI Pin fehlt"
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
#, c-format
@ -1415,7 +1416,7 @@ msgstr "Kein I2C-Gerät an Adresse: 0x%x"
#: supervisor/shared/web_workflow/web_workflow.c
msgid "No IP"
msgstr ""
msgstr "Keine IP"
#: ports/espressif/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
msgid "No MISO pin"
msgstr ""
msgstr "Miso Pin fehlt"
#: ports/espressif/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
msgid "No MOSI pin"
msgstr ""
msgstr "MOSI Pin fehlt"
#: ports/atmel-samd/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
msgid "Off"
msgstr ""
msgstr "Aus"
#: supervisor/shared/bluetooth/bluetooth.c
msgid "Ok"
msgstr ""
msgstr "Ok"
#: ports/atmel-samd/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/stm/common-hal/alarm/time/TimeAlarm.c
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/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
msgid "PWM restart"
msgstr ""
msgstr "PWM Neustart"
#: ports/raspberrypi/common-hal/countio/Counter.c
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/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "RS485"
msgstr ""
msgstr "RS485"
#: ports/espressif/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
msgid "Reconnecting"
msgstr ""
msgstr "Wiederherstellung der Verbindungen"
#: shared-bindings/displayio/EPaperDisplay.c
msgid "Refresh too soon"
@ -1876,7 +1877,7 @@ msgstr "SD-Card CSD-Format nicht unterstützt"
#: ports/cxd56/common-hal/sdioio/SDCard.c
msgid "SDCard init"
msgstr ""
msgstr "SDCard Initialisierung"
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
@ -1894,7 +1895,7 @@ msgstr "SPI-Konfiguration fehlgeschlagen"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI init error"
msgstr ""
msgstr "SPI Initialisierungsfehler"
#: ports/raspberrypi/common-hal/busio/SPI.c
msgid "SPI peripheral in use"
@ -1902,7 +1903,7 @@ msgstr "SPI-Peripheriegeräte wird bereits verwendet"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI re-init"
msgstr ""
msgstr "SPI wird erneut initialisiert"
#: shared-bindings/is31fl3741/FrameBuffer.c
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
msgid "Too many channels in sample"
msgstr ""
msgstr "Zu viele Kanäle im Beispiel"
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample."
@ -2110,20 +2111,20 @@ msgstr "Tuple- oder struct_time-Argument erforderlich"
#: ports/stm/common-hal/busio/UART.c
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/espressif/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
msgid "UART init"
msgstr ""
msgstr "UART Initialisierung"
#: ports/stm/common-hal/busio/UART.c
msgid "UART re-init"
msgstr ""
msgstr "UART wird wieder Initialisiert"
#: ports/stm/common-hal/busio/UART.c
msgid "UART write"
msgstr ""
msgstr "UART wird geschrieben"
#: shared-module/usb_hid/Device.c
msgid "USB busy"
@ -2277,7 +2278,7 @@ msgstr "Nicht unterstütztes Format"
#: shared-bindings/hashlib/__init__.c
msgid "Unsupported hash algorithm"
msgstr ""
msgstr "Hash Algorithmus wird nicht unterstützt"
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Update Failed"
@ -2349,7 +2350,7 @@ msgstr ""
#: supervisor/shared/web_workflow/web_workflow.c
msgid "Wi-Fi: "
msgstr ""
msgstr "Wi-Fi: "
#: main.c
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
msgid "array has too many dimensions"
msgstr ""
msgstr "Das Array hat zu viele Dimensionen"
#: py/objarray.c shared-bindings/alarm/SleepMemory.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/Rectangle.c
msgid "can only have one parent"
msgstr ""
msgstr "kann nur ein Elternteil haben"
#: py/emitinlinethumb.c
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
msgid "channel re-init"
msgstr ""
msgstr "Kanal wird erneut initialisiert"
#: shared-bindings/_stage/Text.c
msgid "chars buffer too small"
@ -2827,7 +2828,7 @@ msgstr "Convolve Argumente dürfen nicht leer sein"
#: extmod/ulab/code/numpy/io/io.c
msgid "corrupted file"
msgstr ""
msgstr "Korrupte Datei"
#: extmod/ulab/code/numpy/poly.c
msgid "could not invert Vandermonde matrix"
@ -2924,7 +2925,7 @@ msgstr "leer"
#: extmod/ulab/code/numpy/io/io.c
msgid "empty file"
msgstr ""
msgstr "Leere Datei"
#: extmod/moduasyncio.c extmod/moduheapq.c extmod/modutimeq.c
msgid "empty heap"
@ -3199,7 +3200,7 @@ msgstr "Indizes müssen Integer, Slices oder Boolesche Listen sein"
#: ports/espressif/common-hal/busio/I2C.c
msgid "init I2C"
msgstr ""
msgstr "initialisiere I2C"
#: extmod/ulab/code/scipy/optimize/optimize.c
msgid "initial values must be iterable"
@ -3248,7 +3249,7 @@ msgstr "Eingabematrix ist singulär"
#: extmod/ulab/code/numpy/create.c
msgid "input must be 1- or 2-d"
msgstr ""
msgstr "Eingabe muss 1- oder 2-d sein"
#: extmod/ulab/code/numpy/carray/carray.c
msgid "input must be a 1D ndarray"
@ -3340,7 +3341,7 @@ msgstr "ungültiger micropython decorator"
#: ports/espressif/common-hal/esp32_camera/Camera.c
msgid "invalid setting"
msgstr ""
msgstr "Invalide Einstellung"
#: shared-bindings/random/__init__.c
msgid "invalid step"
@ -3470,7 +3471,7 @@ msgstr "max_length muss 0-%d sein, wenn fixed_length %s ist"
#: extmod/ulab/code/ndarray.c
msgid "maximum number of dimensions is "
msgstr ""
msgstr "Maximale Anzahl an Dimensionen ist "
#: py/runtime.c
msgid "maximum recursion depth exceeded"
@ -3717,7 +3718,7 @@ msgstr "String mit ungerader Länge"
#: supervisor/shared/web_workflow/web_workflow.c
msgid "off"
msgstr ""
msgstr "aus"
#: extmod/ulab/code/utils/utils.c
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
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
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
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/beetle-esp32-c3/mpconfigboard.h
@ -4153,7 +4154,7 @@ msgstr "Zeitlimit beim warten auf v2 Karte"
#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "timer re-init"
msgstr ""
msgstr "Timer wird neu initialisiert"
#: shared-bindings/time/__init__.c
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
msgid "usecols is too high"
msgstr ""
msgstr "usecols ist zu hoch/groß"
#: extmod/ulab/code/numpy/io/io.c
msgid "usecols keyword must be specified"
msgstr ""
msgstr "usecols muss definiert sein"
#: py/objint.c
#, c-format
@ -4378,7 +4379,7 @@ msgstr "falsche Achse gewählt"
#: extmod/ulab/code/numpy/io/io.c
msgid "wrong dtype"
msgstr ""
msgstr "Falsches dtype"
#: extmod/ulab/code/numpy/transform.c
msgid "wrong index type"
@ -4396,7 +4397,7 @@ msgstr "falsche Länge des Array von Bedingungen"
#: extmod/ulab/code/numpy/transform.c
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
msgid "wrong number of arguments"

View File

@ -6,7 +6,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 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"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n"
@ -412,7 +412,7 @@ msgstr "All I2C-kringutrustning används"
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c
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/frequencyio/FrequencyIn.c
@ -3314,7 +3314,7 @@ msgstr "ogiltig mikropython-dekorator"
#: ports/espressif/common-hal/esp32_camera/Camera.c
msgid "invalid setting"
msgstr ""
msgstr "ogiltig inställning"
#: shared-bindings/random/__init__.c
msgid "invalid step"

View File

@ -7,15 +7,15 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2022-04-19 17:07+0000\n"
"Last-Translator: Siyabend Ürün <urunsiyabend@gmail.com>\n"
"PO-Revision-Date: 2022-08-14 12:14+0000\n"
"Last-Translator: Can Kocyigit <cank3698@googlemail.com>\n"
"Language-Team: none\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.12-dev\n"
"X-Generator: Weblate 4.14-dev\n"
#: main.c
msgid ""
@ -86,7 +86,7 @@ msgstr ""
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
msgstr "%q"
#: shared-bindings/microcontroller/Pin.c
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
msgid "%q and %q must be different"
msgstr ""
msgstr "%q ve %q farklı olmalılar"
#: shared-bindings/microcontroller/Pin.c
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 (serial_connected() && serial_bytes_available()) {
if (serial_connected() && serial_bytes_available() && !autoreload_pending()) {
// Skip REPL if reload was requested.
skip_repl = serial_read() == CHAR_CTRL_D;
if (skip_repl) {

View File

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

View File

@ -30,7 +30,9 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#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_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_SCK), MP_ROM_PTR(&pin_GPIO36) },
{ 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_DC), MP_ROM_PTR(&pin_GPIO39) },
{ MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO40) },
{ MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_TFT_DC), 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_GPIO38) },
{ MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_CARD_POWER), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO2) },
{ 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_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_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) {
// 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;
}

View File

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

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_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);
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;
}

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_SDA (&pin_GPIO42)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_SDA (&pin_GPIO3)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO33)
#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_SDA (&pin_GPIO42)

View File

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

View File

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

View File

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

View File

@ -30,7 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32-C3FN4"
// Status LED
#define MICROPY_HW_NEOPIXEL (&pin_GPIO10)
#define MICROPY_HW_LED_STATUS (&pin_GPIO10)
#define CIRCUITPY_BOARD_I2C (1)
#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_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_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_SDA (&pin_GPIO42)

View File

@ -28,3 +28,5 @@
#define MICROPY_HW_BOARD_NAME "BastWiFi"
#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) {
}
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_MCU_NAME "ESP32"
#define MICROPY_HW_LED_STATUS (&pin_GPIO21)
#define CIRCUITPY_BOARD_I2C (1)
#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_CS), MP_ROM_PTR(&pin_GPIO44) },
{ 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_SPI), MP_ROM_PTR(&board_spi_obj) },

View File

@ -31,5 +31,8 @@
#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_RX (&pin_GPIO44)

View File

@ -31,6 +31,9 @@
#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_SDA (&pin_GPIO41)

View File

@ -31,5 +31,8 @@
#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_RX (&pin_GPIO44)

View File

@ -31,6 +31,9 @@
#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_SDA (&pin_GPIO41)

View File

@ -30,7 +30,7 @@
#define MICROPY_HW_MCU_NAME "ESP32S2"
#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_SDA (&pin_GPIO8)

View File

@ -15,22 +15,6 @@ bool board_requests_safe_mode(void) {
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) {
}

View File

@ -15,22 +15,6 @@ bool board_requests_safe_mode(void) {
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) {
}

View File

@ -29,6 +29,8 @@
#define MICROPY_HW_BOARD_NAME "S2Mini"
#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_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_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_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_MCU_NAME "ESP32-C3FN4"
// Status LED
// Status LEDs
#define MICROPY_HW_NEOPIXEL (&pin_GPIO7)
#define MICROPY_HW_NEOPIXEL_COUNT (2)
#define MICROPY_HW_LED_STATUS (&pin_GPIO8)
// Default bus pins
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5)

View File

@ -42,17 +42,6 @@ bool board_requests_safe_mode(void) {
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) {
}

View File

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

View File

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

View File

@ -32,6 +32,8 @@
// #define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
// #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_SDA (&pin_GPIO8)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO40)
#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_SDA (&pin_GPIO8)

View File

@ -32,6 +32,8 @@
// #define MICROPY_HW_APA102_MOSI (&pin_GPIO40)
// #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_SDA (&pin_GPIO33)

View File

@ -32,6 +32,8 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO40)
#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_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_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;
}
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
// 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_pulldown_en(pin_number);
}
#endif
}
// Mark pin as free and return it to a quiescent state.

View File

@ -30,22 +30,9 @@
#include "peripherals/touch.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,
const mcu_pin_obj_t *pin) {
if (pin->touch_channel == TOUCH_PAD_MAX) {
if (pin->touch_channel == NO_TOUCH_CHANNEL) {
raise_ValueError_invalid_pin();
}
claim_pin(pin);
@ -53,15 +40,12 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self,
// initialize touchpad
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.
// 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.
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) {
@ -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) {
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) {
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) {

View File

@ -43,7 +43,7 @@ void peripherals_touch_never_reset(const bool enable) {
void peripherals_touch_init(const touch_pad_t touchpad) {
if (!touch_inited) {
touch_pad_init();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW);
}
// 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
@ -52,13 +52,27 @@ void peripherals_touch_init(const touch_pad_t touchpad) {
touch_pad_config(touchpad, 0);
#else
touch_pad_config(touchpad);
touch_pad_fsm_start();
#endif
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
if (!touch_inited) {
#if defined(CONFIG_IDF_TARGET_ESP32)
touch_pad_sw_start();
#else
touch_pad_fsm_start();
#endif
touch_inited = true;
}
}

View File

@ -29,6 +29,7 @@
#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_never_reset(const bool enable);
extern void peripherals_touch_init(const touch_pad_t touchpad);

View File

@ -345,9 +345,6 @@ void reset_port(void) {
reset_all_pins();
// A larger delay so the idle task can run and do any IDF cleanup needed.
vTaskDelay(4);
#if CIRCUITPY_ANALOGIO
analogout_reset();
#endif
@ -402,6 +399,9 @@ void reset_port(void) {
#if CIRCUITPY_WATCHDOG
watchdog_reset();
#endif
// Yield so the idle task can run and do any IDF cleanup needed.
port_yield();
}
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) {
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.
# Use PWM interally
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CTARGET = 0
CIRCUITPY_I2CTARGET = 1
CIRCUITPY_NVM = 1
# Use PIO interally
CIRCUITPY_PULSEIO ?= 1

View File

@ -31,6 +31,7 @@
#include "py/objstr.h"
#include "py/stream.h"
#include "py/runtime.h"
#include "py/unicode.h"
#include "supervisor/shared/translate/translate.h"
// 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)
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
// before error condition occurred. If *errcode == 0, returns total bytes written (which will
// 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(&mp_type_str, &vstr);
return mp_obj_new_str_from_vstr_check(&mp_type_str, &vstr);
}
#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);
} else {
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;
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.
@ -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);

View File

@ -109,6 +109,11 @@ void port_wake_main_task(void);
// default weak implementation is provided that does nothing.
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.
// This function is called once while boot.py's VM is still valid, and
// then a second time after the VM is finalized.

View File

@ -47,11 +47,11 @@
#include "supervisor/shared/reload.h"
#include "supervisor/shared/bluetooth/file_transfer.h"
#include "supervisor/shared/bluetooth/file_transfer_protocol.h"
#include "supervisor/shared/workflow.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "py/mpstate.h"
#include "py/stackctrl.h"
STATIC bleio_service_obj_t supervisor_ble_service;
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;
}
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) {
const struct delete_command *command = (struct delete_command *)raw_buf;
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);
if (result == FR_OK) {
if ((file.fattrib & AM_DIR) != 0) {
result = _delete_directory_contents(fs, path);
result = supervisor_workflow_delete_directory_contents(fs, path);
}
if (result == FR_OK) {
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;
response.truncated_time = truncate_time(command->modification_time, &fattime);
override_fattime(fattime);
FRESULT result = f_mkdir(fs, path);
FRESULT result = supervisor_workflow_mkdir_parents(fs, path);
override_fattime(0);
#if CIRCUITPY_USB_MSC
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_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>
<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>
<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>
<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>
</table>
<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>
+📁&nbsp;<input type="text" id="name"><button type="submit" id="mkdir">Create Directory</button>
</body></html>

View File

@ -1,20 +1,27 @@
let new_directory_name = document.getElementById("name");
let files = document.getElementById("files");
let dirs = document.getElementById("dirs");
var url_base = window.location;
var current_path;
var editable = undefined;
async function refresh_list() {
function compareValues(a, b) {
if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) {
return 0;
} else {
return a.directory.toString().substring(3,4)+a.name.toLowerCase() < b.directory.toString().substring(3,4)+b.name.toLowerCase() ? -1 : 1;
}
function compareValues(a, b) {
if (a.directory == b.directory && a.name.toLowerCase() === b.name.toLowerCase()) {
return 0;
} else if (a.directory != b.directory) {
return a.directory < b.directory ? 1 : -1;
} else {
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);
if (current_path == "") {
current_path = "/";
@ -45,14 +52,14 @@ async function refresh_list() {
);
editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE");
new_directory_name.disabled = !editable;
files.disabled = !editable;
set_upload_enabled(editable);
if (!editable) {
let usbwarning = document.querySelector("#usbwarning");
usbwarning.style.display = "block";
}
}
if (window.location.path != "/fs/") {
if (current_path != "/") {
var clone = template.content.cloneNode(true);
var td = clone.querySelectorAll("td");
td[0].textContent = "📁";
@ -62,6 +69,8 @@ async function refresh_list() {
path.textContent = "..";
// Remove the delete button
td[4].replaceChildren();
td[5].replaceChildren();
td[6].replaceChildren();
new_children.push(clone);
}
@ -82,31 +91,46 @@ async function refresh_list() {
file_path = api_url;
}
var text_file = false;
if (f.directory) {
icon = "📁";
} else if(f.name.endsWith(".txt") ||
f.name.endsWith(".env") ||
f.name.endsWith(".py") ||
f.name.endsWith(".js") ||
f.name.endsWith(".json")) {
icon = "📄";
text_file = true;
} else if (f.name.endsWith(".html")) {
icon = "🌐";
text_file = true;
}
td[0].textContent = icon;
td[1].textContent = f.file_size;
var path = clone.querySelector("a");
var path = clone.querySelector("a.path");
path.href = file_path;
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");
delete_button.value = api_url;
delete_button.disabled = !editable;
delete_button.onclick = del;
if (editable && !f.directory) {
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");
if (text_file && editable && !f.directory) {
edit_url = new URL(edit_url, url_base);
let edit_link = clone.querySelector(".edit_link");
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);
@ -148,8 +172,25 @@ async function mkdir(e) {
}
async function upload(e) {
for (const file of files.files) {
let file_path = new URL("/fs" + current_path + file.name, url_base);
set_upload_enabled(false);
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,
{
method: "PUT",
@ -163,9 +204,12 @@ async function upload(e) {
if (response.ok) {
refresh_list();
}
progress.value += 1;
}
files.value = "";
upload_button.disabled = true;
dirs.value = "";
progress.value = 0;
set_upload_enabled(true);
}
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();
let mkdir_button = document.getElementById("mkdir");
mkdir_button.onclick = mkdir;
let upload_button = document.getElementById("upload");
upload_button.onclick = upload;
upload_button.disabled = files.files.length == 0;
files.onchange = () => {
upload_button.disabled = files.files.length == 0;
}
files.onchange = upload;
dirs.onchange = upload;
mkdir_button.disabled = new_directory_name.value.length == 0;

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<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="/style.css">
</head>

View File

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

View File

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

View File

@ -37,10 +37,12 @@
#include "shared/timeutils/timeutils.h"
#include "supervisor/fatfs_port.h"
#include "supervisor/filesystem.h"
#include "supervisor/port.h"
#include "supervisor/shared/reload.h"
#include "supervisor/shared/translate/translate.h"
#include "supervisor/shared/web_workflow/web_workflow.h"
#include "supervisor/shared/web_workflow/websocket.h"
#include "supervisor/shared/workflow.h"
#include "supervisor/usb.h"
#include "shared-bindings/hashlib/__init__.h"
@ -77,8 +79,9 @@ typedef struct {
enum request_state state;
char method[8];
char path[256];
char destination[256];
char header_key[64];
char header_value[64];
char header_value[256];
// We store the origin so we can reply back with it.
char origin[64];
size_t content_length;
@ -323,22 +326,31 @@ void supervisor_start_web_workflow(void) {
#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;
while (sent == -EAGAIN && common_hal_socketpool_socket_get_connected(socket)) {
sent = socketpool_socket_send(socket, buf, len);
while ((sent == -EAGAIN || (sent > 0 && total_sent < 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);
}
}
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) {
_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.
@ -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) {
mp_print_t _socket_print = {socket, _print_raw};
mp_printf(&_socket_print, "%X\r\n", strlen(chunk));
_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 *)chunk, strlen(chunk));
web_workflow_send_raw(socket, (const uint8_t *)"\r\n", 2);
}
STATIC void _print_chunk(void *env, const char *str, size_t len) {
mp_print_t _socket_print = {env, _print_raw};
mp_printf(&_socket_print, "%X\r\n", len);
_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 *)str, len);
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.
@ -543,6 +555,15 @@ static void _reply_conflict(socketpool_socket_obj_t *socket, _request *request)
_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) {
_send_strs(socket,
"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, "");
}
// 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.
// This function truncates the time the time to a resolution storable by FATFS and fills in the
// 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;
STATIC_FILE(code_html);
STATIC_FILE(directory_html);
STATIC_FILE(directory_js);
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-Type: ", content_type, "\r\n",
"\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)
@ -976,6 +964,28 @@ static uint8_t _hex2nibble(char h) {
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) {
if (request->redirect) {
_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.
// We only do this on /fs/ paths and after redirect so that any
// path echoing we do stays encoded.
size_t o = 0;
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';
}
_decode_percents(request->path);
char *path = request->path + 3;
size_t pathlen = strlen(path);
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);
if (result == FR_OK) {
if ((file.fattrib & AM_DIR) != 0) {
result = _delete_directory_contents(fs, path);
result = supervisor_workflow_delete_directory_contents(fs, path);
}
if (result == FR_OK) {
result = f_unlink(fs, path);
@ -1056,6 +1051,34 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
_reply_no_content(socket, request);
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) {
if (strcasecmp(request->method, "GET") == 0) {
FF_DIR dir;
@ -1088,7 +1111,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
truncate_time(request->timestamp_ms * 1000000, &fattime);
override_fattime(fattime);
}
FRESULT result = f_mkdir(fs, path);
FRESULT result = supervisor_workflow_mkdir_parents(fs, path);
override_fattime(0);
#if CIRCUITPY_USB_MSC
usb_msc_unlock();
@ -1133,6 +1156,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
} else {
_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) {
const char *path = request->path + 3;
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 &&
strlen(request->header_value) == 24) {
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);
} else if (request->offset > sizeof(request->header_value) - 1) {

View File

@ -28,6 +28,8 @@
#include <stdbool.h>
#include "shared-bindings/socketpool/Socket.h"
// This background function should be called repeatedly. It cannot be done based
// on events.
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_start_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 "shared/runtime/interrupt_char.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.
#include "esp_log.h"
@ -77,7 +78,7 @@ void websocket_handoff(socketpool_socket_obj_t *socket) {
}
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) {
@ -91,16 +92,6 @@ static bool _read_byte(uint8_t *c) {
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) {
uint8_t 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");
}
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)) {
// Send the payload back to the client.
cp_serial.frame_index++;
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) {
@ -231,23 +222,23 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) {
payload_len = 127;
}
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];
if (payload_len == 126) {
extended_len[0] = (len >> 8) & 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) {
uint32_t zero = 0;
// 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[1] = (len >> 16) & 0xff;
extended_len[2] = (len >> 8) & 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) {
@ -255,6 +246,9 @@ void websocket_write(const char *text, size_t len) {
}
void websocket_background(void) {
if (!websocket_connected()) {
return;
}
uint8_t c;
while (ringbuf_num_empty(&_incoming_ringbuf) > 0 &&
_read_next_payload_byte(&c)) {

View File

@ -26,6 +26,8 @@
#include <stdbool.h>
#include "py/mpconfig.h"
#include "py/mpstate.h"
#include "py/stackctrl.h"
#include "supervisor/background_callback.h"
#include "supervisor/workflow.h"
#include "supervisor/serial.h"
@ -46,6 +48,8 @@
#endif
static background_callback_t workflow_background_cb;
static bool workflow_started = false;
static void workflow_background(void *data) {
#if CIRCUITPY_WEB_WORKFLOW
supervisor_web_workflow_background();
@ -68,6 +72,9 @@ void supervisor_workflow_reset(void) {
}
void supervisor_workflow_request_background(void) {
if (!workflow_started) {
return;
}
background_callback_add_core(&workflow_background_cb);
}
@ -114,4 +121,63 @@ void supervisor_workflow_start(void) {
#if CIRCUITPY_WEB_WORKFLOW
supervisor_start_web_workflow();
#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
#include "lib/oofatfs/ff.h"
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
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 :]
decoder = qrio.QRDecoder(320, 240)