merge from adafruit/main

This commit is contained in:
Dan Halbert 2022-07-08 15:42:19 -04:00
commit c316b950c7
76 changed files with 2656 additions and 408 deletions

View File

@ -287,12 +287,13 @@ jobs:
fetch-depth: 1
- name: Get CP deps
run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }}
- uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '10-2020-q4'
- name: Install dependencies
run: |
sudo apt-get install -y gettext
pip install -r requirements-ci.txt -r requirements-dev.txt
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
- name: Versions
run: |
gcc --version
@ -487,8 +488,9 @@ jobs:
pip install -r requirements-ci.txt -r requirements-dev.txt
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
sudo tar -C /usr --strip-components=1 -xaf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
- uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '10-2020-q4'
- name: Install mkfs.fat
run: |
wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz

19
.gitmodules vendored
View File

@ -145,8 +145,8 @@
url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git
[submodule "ports/espressif/esp-idf"]
path = ports/espressif/esp-idf
url = https://github.com/espressif/esp-idf.git
branch = release/v4.4
url = https://github.com/adafruit/esp-idf.git
branch = circuitpython8
[submodule "ports/espressif/certificates/nina-fw"]
path = ports/espressif/certificates/nina-fw
url = https://github.com/adafruit/nina-fw.git
@ -292,3 +292,18 @@
[submodule "frozen/mixgo_cp_lib"]
path = frozen/mixgo_cp_lib
url = https://github.com/dahanzimin/circuitpython_lib.git
[submodule "frozen/Adafruit_CircuitPython_IS31FL3731"]
path = frozen/Adafruit_CircuitPython_IS31FL3731
url = https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3731.git
[submodule "frozen/Adafruit_CircuitPython_Ticks"]
path = frozen/Adafruit_CircuitPython_Ticks
url = https://github.com/adafruit/Adafruit_CircuitPython_Ticks.git
[submodule "frozen/Adafruit_CircuitPython_asyncio"]
path = frozen/Adafruit_CircuitPython_asyncio
url = https://github.com/adafruit/Adafruit_CircuitPython_asyncio.git
[submodule "frozen/circuitpython_ef_music"]
path = frozen/circuitpython_ef_music
url = https://github.com/elecfreaks/circuitpython_ef_music.git
[submodule "frozen/circuitpython_picoed"]
path = frozen/circuitpython_picoed
url = https://github.com/elecfreaks/circuitpython_picoed.git

View File

@ -70,7 +70,7 @@ The test suite in the top level `tests` directory. It needs the unix port to ru
Then you can run the test suite:
cd ../../tests
./run-tests
./run-tests.py
A successful run will say something like

View File

@ -90,9 +90,11 @@ If you'd like to use the term "CircuitPython" and Blinka for your product here i
* Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source
`here <https://github.com/adafruit/circuitpython-org/>`_). This is to ensure that a user of your
product can always download the latest version of CircuitPython from the standard place.
* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in
AND/OR provides file and serial access over Bluetooth Low Energy. Boards that do not support USB
should be clearly marked as BLE-only CircuitPython.
* Your product supports at least one standard "`Workflow <https://docs.circuitpython.org/en/latest/docs/workflows.html>`__" for serial and file access:
* With a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
* With file and serial access over Bluetooth Low Energy using the BLE Workflow.
* With file access over WiFi using the WiFi Workflow with serial access over USB and/or WebSocket.
* Boards that do not support the USB Workflow should be clearly marked.
If you choose not to meet these requirements, then we ask you call your version of CircuitPython
something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is

View File

@ -22,6 +22,7 @@ Full Table of Contents
supported_ports.rst
troubleshooting.rst
drivers.rst
workflows
environment.rst
.. toctree::

364
docs/workflows.md Normal file
View File

@ -0,0 +1,364 @@
# Workflows
Workflows are the process used to 1) manipulate files on the CircuitPython device and 2) interact
with the serial connection to CircuitPython. The serial connection is usually used to access the
REPL.
Starting with CircuitPython 3.x we moved to a USB-only workflow. Prior to that, we used the serial
connection alone to do the whole workflow. In CircuitPython 7.x, a BLE workflow was added with the
advantage of working with mobile devices. CircuitPython 8.x added a web workflow that works over the
local network (usually Wi-Fi) and a web browser. Other clients can also use the Web REST API. Boards
should clearly document which workflows are supported.
Code for workflows lives in `supervisor/shared`.
The workflow APIs are documented here.
## USB
These USB interfaces are enabled by default on boards with USB support. They are usable once the
device has been plugged into a host.
### CIRCUITPY drive
CircuitPython exposes a standard mass storage (MSC) interface to enable file manipulation over a
standard interface. This interface works underneath the file system at the block level so using it
excludes other types of workflows from manipulating the file system at the same time.
### CDC serial
CircuitPython exposes one CDC USB interface for CircuitPython serial. This is a standard serial
USB interface.
TODO: Document how it designates itself from the user CDC.
Setting baudrate 1200 and disconnecting will reboot into a bootloader. (Used by Arduino to trigger
a reset into bootloader.)
## BLE
The BLE workflow is enabled for nRF boards. By default, to prevent malicious access, it is disabled.
To connect to the BLE workflow, press the reset button while the status led blinks blue quickly
after the safe mode blinks. The board will restart and broadcast the file transfer service UUID
(`0xfebb`) along with the board's [Creation IDs](https://github.com/creationid/creators). This
public broadcast is done at a lower transmit level so the devices must be closer. On connection, the
device will need to pair and bond. Once bonded, the device will broadcast whenever disconnected
using a rotating key rather than a static one. Non-bonded devices won't be able to resolve it. After
connection, the central device can discover two default services. One for file transfer and one for
CircuitPython specifically that includes serial characteristics.
### File Transfer API
CircuitPython uses [an open File Transfer API](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer)
to enable file system access.
### CircuitPython Service
The base UUID for the CircuitPython service is `ADAFXXXX-4369-7263-7569-7450794686e`. The `XXXX` is
replaced by the four specific digits below. The service itself is `0001`.
#### TX - `0002` / RX - `0003`
These characteristic work just like the Nordic Uart Service (NUS) but have different UUIDs to prevent
conflicts with user created NUS services.
#### Version - `0100`
Read-only characteristic that returns the UTF-8 encoded version string.
## Web
The web workflow is depends on adding Wi-Fi credentials into the `/.env` file. The keys are
`CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD`. Once these are defined, CircuitPython will
automatically connect to the network and start the webserver used for the workflow. The webserver
is on port 80. It also enables MDNS.
Here is an example `/.env`:
```bash
# To auto-connect to Wi-Fi
CIRCUITPY_WIFI_SSID='scottswifi'
CIRCUITPY_WIFI_PASSWORD='secretpassword'
# To enable modifying files from the web. Change this too!
CIRCUITPY_WEB_API_PASSWORD='passw0rd'
```
MDNS is used to resolve [`circuitpython.local`](http://circuitpython.local) to a device specific
hostname of the form `cpy-XXXXXX.local`. The `XXXXXX` is based on network MAC address. The device
also provides the MDNS service with service type `_circuitpython` and protocol `_tcp`.
### HTTP
The web server is HTTP 1.1 and may use chunked responses so that it doesn't need to precompute
content length.
The API generally consists of an HTTP method such as GET or PUT and a path. Requests and responses
also have headers. Responses will contain a status code and status text such as `404 Not Found`.
This API tries to use standard status codes to encode the status of the various operations. The
[Mozilla Developer Network HTTP docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP)
are a great reference.
#### Examples
The examples use `curl`, a common command line program for issuing HTTP requests. The examples below
use `circuitpython.local` as the easiest way to work. If you have multiple active devices, you'll
want to use the specific `cpy-XXXXXX.local` version.
The examples also use `passw0rd` as the password placeholder. Replace it with your password before
running the example.
### `/`
The root welcome page links to the file system page and also displays other CircuitPython devices
found using MDNS service discovery. This allows web browsers to find other devices from one. (All
devices will respond to `circuitpython.local` so the device redirected to may vary.)
### CORS
The web server will allow requests from `cpy-XXXXXX.local`, `127.0.0.1`, the device's IP and
`code.circuitpython.org`. (`circuitpython.local` requests will be redirected to `cpy-XXXXXX.local`.)
### File REST API
All file system related APIs are protected by HTTP basic authentication. It is *NOT* secure but will
hopefully prevent some griefing in shared settings. The password is sent unencrypted so do not reuse
a password with something important.
The password is taken from `/.env` with the key `CIRCUITPY_WEB_API_PASSWORD`. If this is unset, the
server will respond with `403 Forbidden`. When a password is set, but not provided in a request, it
will respond `401 Unauthorized`.
#### `/fs/`
The `/fs/` page will respond with a directory browsing HTML once authenticated. This page is always
gzipped. If the `Accept: application/json` header is provided, then the JSON representation of the
root will be returned.
##### OPTIONS
When requested with the `OPTIONS` method, the server will respond with CORS related headers. Most
aren't needed for API use. They are there for the web browser.
* `Access-Control-Allow-Methods` - Varies with USB state. `GET, OPTIONS` when USB is active. `GET, OPTIONS, PUT, DELETE` otherwise.
Example:
```sh
curl -v -u :passw0rd -X OPTIONS -L --location-trusted http://circuitpython.local/fs/
```
#### `/fs/<directory path>/`
Directory paths must end with a /. Otherwise, the path is assumed to be a file.
##### GET
Returns a JSON representation of the directory.
* `200 OK` - Directory exists and JSON returned
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing directory
Returns information about each file in the directory:
* `name` - File name. No trailing `/` on directory names
* `directory` - `true` when a directory. `false` otherwise
* `modified_ns` - File modification time in nanoseconds since January 1st, 1970. May not use full resolution
* `file_size` - File size in bytes. `0` for directories
Example:
```sh
curl -v -u :passw0rd -H "Accept: application/json" -L --location-trusted http://circuitpython.local/fs/lib/hello/
```
```json
[
{
"name": "world.txt",
"directory": false,
"modified_ns": 946934328000000000,
"file_size": 12
}
]
```
##### PUT
Tries to make a directory at the given path. Request body is ignored. The custom `X-Timestamp`
header can provide a timestamp in milliseconds since January 1st, 1970 (to match JavaScript's file
time resolution) used for the directories modification time. The RTC time will used otherwise.
Returns:
* `204 No Content` - Directory exists
* `201 Created` - Directory created
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `409 Conflict` - USB is active and preventing file system modification
* `404 Not Found` - Missing parent directory
* `500 Server Error` - Other, unhandled error
Example:
```sh
curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
```
##### DELETE
Deletes the directory and all of its contents.
* `204 No Content` - Directory and its contents deleted
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - No directory
* `409 Conflict` - USB is active and preventing file system modification
Example:
```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
```
#### `/fs/<file path>`
##### PUT
Stores the provided content to the file path.
The custom `X-Timestamp` header can provide a timestamp in milliseconds since January 1st, 1970
(to match JavaScript's file time resolution) used for the directories modification time. The RTC
time will used otherwise.
Returns:
* `201 Created` - File created and saved
* `204 No Content` - File existed and overwritten
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing parent directory
* `409 Conflict` - USB is active and preventing file system modification
* `413 Payload Too Large` - `Expect` header not sent and file is too large
* `417 Expectation Failed` - `Expect` header sent and file is too large
* `500 Server Error` - Other, unhandled error
If the client sends the `Expect` header, the server will reply with `100 Continue` when ok.
Example:
```sh
echo "Hello world" >> test.txt
curl -v -u :passw0rd -T test.txt -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### GET
Returns the raw file contents. `Content-Type` will be set based on extension:
* `text/plain` - `.py`, `.txt`
* `text/javascript` - `.js`
* `text/html` - `.html`
* `application/json` - `.json`
* `application/octet-stream` - Everything else
Will return:
* `200 OK` - File exists and file returned
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - Missing file
Example:
```sh
curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
##### DELETE
Deletes the file.
* `204 No Content` - File existed and deleted
* `401 Unauthorized` - Incorrect password
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
* `404 Not Found` - File not found
* `409 Conflict` - USB is active and preventing file system modification
Example:
```sh
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
```
### `/cp/`
`/cp/` serves basic info about the CircuitPython device and others discovered through MDNS. It is
not protected by basic auth in case the device is someone elses.
Only `GET` requests are supported and will return `405 Method Not Allowed` otherwise.
#### `/cp/version.json`
Returns information about the device.
* `web_api_version`: Always `1`. This versions the rest of the API and new versions may not be backwards compatible.
* `version`: CircuitPython build version.
* `build_date`: CircuitPython build date.
* `board_name`: Human readable name of the board.
* `mcu_name`: Human readable name of the microcontroller.
* `board_id`: Board id used in code and on circuitpython.org.
* `creator_id`: Creator ID for the board.
* `creation_id`: Creation ID for the board, set by the creator.
* `hostname`: MDNS hostname.
* `port`: Port of CircuitPython Web Service.
* `ip`: IP address of the device.
Example:
```sh
curl -v -L http://circuitpython.local/cp/version.json
```
```json
{
"web_api_version": 1,
"version": "8.0.0-alpha.1-20-ge1d4518a9-dirty",
"build_date": "2022-06-24",
"board_name": "ESP32-S3-USB-OTG-N8",
"mcu_name": "ESP32S3",
"board_id": "espressif_esp32s3_usb_otg_n8",
"creator_id": 12346,
"creation_id": 28683,
"hostname": "cpy-f57ce8",
"port": 80,
"ip": "192.168.1.94"
}
```
#### `/cp/devices.json`
Returns information about other devices found on the network using MDNS.
* `total`: Total MDNS response count. May be more than in `devices` if internal limits were hit.
* `devices`: List of discovered devices.
* `hostname`: MDNS hostname
* `instance_name`: MDNS instance name. Defaults to human readable board name.
* `port`: Port of CircuitPython Web API
* `ip`: IP address
Example:
```sh
curl -v -L http://circuitpython.local/cp/devices.json
```
```json
{
"total": 1,
"devices": [
{
"hostname": "cpy-951032",
"instance_name": "Adafruit Feather ESP32-S2 TFT",
"port": 80,
"ip": "192.168.1.235"
}
]
}
```
### Static files
* `/favicon.ico` - Blinka
* `/directory.js` - JavaScript for `/fs/`
* `/welcome.js` - JavaScript for `/`
### WebSocket
Coming soon!

@ -0,0 +1 @@
Subproject commit b4a0461889ead5da69f4ed6d0118276b01613981

@ -0,0 +1 @@
Subproject commit 6757c5b37cf26458448930042cb0a41f8ad0a5ef

@ -0,0 +1 @@
Subproject commit c496cfb5768cd506d61100284fdab94dd439ec3b

@ -0,0 +1 @@
Subproject commit 6e8eedb1475e2b91f8dea7bceebb20e44d70b171

@ -0,0 +1 @@
Subproject commit d890d23f4261722338280f284cc1640e22e50e14

@ -1 +1 @@
Subproject commit 837f3e5f16accae5b3677954921b5ddd517f0799
Subproject commit 6452f2a78f32cf3b5d07e699f26d25e9c4d10d09

View File

@ -78,7 +78,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -438,7 +438,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "Semua channel event sedang digunakan"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -524,7 +523,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1175,6 +1174,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "Kesalahan internal #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2275,10 +2278,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3947,10 +3946,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -72,7 +72,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -432,7 +432,6 @@ msgstr ""
msgid "All event channels in use"
msgstr ""
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -518,7 +517,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1160,6 +1159,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2244,10 +2247,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3915,10 +3914,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -79,7 +79,7 @@ msgstr "%d adresní pin, %d rgb pin a %d dlaždice indikuje výšku %d, ne %d"
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr "%q"
@ -439,7 +439,6 @@ msgstr "Všechny kanály jsou používány"
msgid "All event channels in use"
msgstr "Všechny kanály událostí jsou již používány"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -525,7 +524,7 @@ msgstr "Konverze audia není implementována"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN nepoužívá heslo"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Autentizace selhala"
@ -1175,6 +1174,10 @@ msgstr "Interní chyba"
msgid "Internal error #%d"
msgstr "Vnitřní chyba #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2262,10 +2265,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3933,10 +3932,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -80,7 +80,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -441,7 +441,6 @@ msgstr "Alle Kanäle werden verwendet"
msgid "All event channels in use"
msgstr "Alle Event-Kanäle werden benutzt"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Alle State-Maschinen in Verwendung"
@ -527,7 +526,7 @@ msgstr "Audio-Konvertierung nicht implementiert"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN wird mit Passwort nicht verwendet"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Authentifizierungsfehler"
@ -1188,6 +1187,10 @@ msgstr "Interner Fehler"
msgid "Internal error #%d"
msgstr "Interner Fehler #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Ungültiger %q"
@ -2307,10 +2310,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout muss größer als 0 sein"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Watchdog timer abgelaufen."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -4012,10 +4011,6 @@ msgstr "source_bitmap muss value_count von 65536 haben"
msgid "source_bitmap must have value_count of 8"
msgstr "source_bitmap muss value_count von 8 haben"
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr "ssid kann nicht mehr als 32 Bytes lang sein"
#: py/objstr.c
msgid "start/end indices"
msgstr "start/end Indizes"
@ -4373,6 +4368,12 @@ msgstr "zi muss eine Gleitkommazahl sein"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi muss die Form (n_section, 2) haben"
#~ msgid "Watchdog timer expired."
#~ msgstr "Watchdog timer abgelaufen."
#~ msgid "ssid can't be more than 32 bytes"
#~ msgstr "ssid kann nicht mehr als 32 Bytes lang sein"
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q muss ein Tupel der Länge 2 sein"

View File

@ -72,7 +72,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -432,7 +432,6 @@ msgstr ""
msgid "All event channels in use"
msgstr ""
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -518,7 +517,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1160,6 +1159,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2244,10 +2247,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3915,10 +3914,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -82,7 +82,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -442,7 +442,6 @@ msgstr "All channels in use"
msgid "All event channels in use"
msgstr "All event channels in use"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "All state machines in use"
@ -528,7 +527,7 @@ msgstr "Audio conversion not implemented"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN is not used with password"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Authentication failure"
@ -1176,6 +1175,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "Internal error #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Invalid %q"
@ -2277,10 +2280,6 @@ msgstr "WatchDogTimer.mode cannot be changed once set to WatchDogMode.RESET"
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout must be greater than 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "WatchDog timer expired."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3954,10 +3953,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr "start/end indices"
@ -4312,6 +4307,9 @@ msgstr "zi must be of float type"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi must be of shape (n_section, 2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "WatchDog timer expired."
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q must be a tuple of length 2"

View File

@ -81,7 +81,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -441,7 +441,6 @@ msgstr "Todos los canales esta en uso"
msgid "All event channels in use"
msgstr "Todos los canales de eventos estan siendo usados"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Todas las máquinas de estado en uso"
@ -529,7 +528,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN no se usa con contraseña"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Fallo de autenticación"
@ -1191,6 +1190,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "Error interno #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "%q inválido"
@ -2309,10 +2312,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout debe ser mayor a 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Temporizador de perro guardián expirado."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3998,10 +3997,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr "índices inicio/final"
@ -4357,6 +4352,9 @@ msgstr "zi debe ser de tipo flotante"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi debe ser una forma (n_section,2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "Temporizador de perro guardián expirado."
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q debe ser una tupla de longitud 2"

View File

@ -73,7 +73,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -436,7 +436,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "Lahat ng event channels ginagamit"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -522,7 +521,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1173,6 +1172,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2264,10 +2267,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3956,10 +3955,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr "start/end indeks"

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
"PO-Revision-Date: 2022-06-03 01:35+0000\n"
"Last-Translator: ajs256 <alex.sirota@icloud.com>\n"
"PO-Revision-Date: 2022-07-06 05:15+0000\n"
"Last-Translator: Maxime Leroy <lisacintosh@gmail.com>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.13-dev\n"
"X-Generator: Weblate 4.13.1-dev\n"
#: main.c
msgid ""
@ -30,6 +30,9 @@ msgid ""
"\n"
"Code stopped by auto-reload. Reloading soon.\n"
msgstr ""
"\n"
"Le code a été arrêté par l'actualisation automatique. Rechargement "
"prochain.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@ -81,7 +84,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr "%q"
@ -115,7 +118,7 @@ msgstr "les indices %q doivent être des entiers, pas %s"
#: shared-module/bitbangio/SPI.c
msgid "%q init failed"
msgstr ""
msgstr "échec de l'initialisation %q"
#: py/argcheck.c
msgid "%q length must be %d"
@ -441,7 +444,6 @@ msgstr "Tout les canaux sont utilisés"
msgid "All event channels in use"
msgstr "Tous les canaux d'événements sont utilisés"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Tous les automates finis sont utilisés"
@ -529,7 +531,7 @@ msgstr "La conversion audio n'est pas implémentée"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN n'est pas utilisé avec un mot de passe"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Échec d'authentification"
@ -556,7 +558,9 @@ msgstr "Au-dessous de la fréquence d'images minimale"
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must be sequential pins"
msgstr "Bit clock et word select doivent êtres sur des broches séquentielles"
msgstr ""
"La sélection du bit d'horloge et de mot doit être sur des broches "
"séquentielles"
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Bit clock and word select must share a clock unit"
@ -601,7 +605,7 @@ msgstr "Tampon + décalage trop petit %d %d %d"
#: ports/raspberrypi/bindings/rp2pio/StateMachine.c
msgid "Buffer elements must be 4 bytes long or less"
msgstr "Éléments du tampon doit être 4 octets ou moins"
msgstr "Les éléments du tampon doivent faire 4 octets ou moins"
#: shared-bindings/framebufferio/FramebufferDisplay.c
msgid "Buffer is not a bytearray."
@ -653,7 +657,7 @@ msgstr "Les blocs CBC doivent être des multiples de 16 octets"
#: supervisor/shared/safe_mode.c
msgid "CIRCUITPY drive could not be found or created."
msgstr ""
msgstr "Lappareil CIRCUITPY ne peut pas être trouvé ou créé."
#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c
msgid "CRC or checksum was invalid"
@ -665,22 +669,22 @@ msgstr "Appelez super().__init__() avant d'accéder à l'objet natif."
#: ports/cxd56/common-hal/camera/Camera.c
msgid "Camera init"
msgstr ""
msgstr "Initialisation de la caméra"
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on RTC IO from deep sleep."
msgstr "L'alarme peut seulement être depuis TRC IO depuis le someil profond."
msgstr "L'alarme ne peut être que sur TRC IO depuis un sommeil profond."
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on one low pin while others alarm high from deep sleep."
msgstr ""
"L'alarme peut seulement être sur une broche basse tandis que d'autres "
"alarment sont sur des broches hautes depuis le someil profond."
"alarment sont sur des broches hautes depuis le sommeil profond."
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Can only alarm on two low pins from deep sleep."
msgstr ""
"L'alarme peut seulement être sur deux broches basses depuis le someil "
"L'alarme peut seulement être sur deux broches basses depuis le sommeil "
"profond."
#: ports/espressif/common-hal/_bleio/Characteristic.c
@ -738,6 +742,7 @@ msgstr "Ne peut démonter '/' quand est visible par USB."
#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c
msgid "Cannot reset into bootloader because no bootloader is present"
msgstr ""
"Impossible de redémarrer dans le bootloader puisque aucun n'est présent"
#: ports/espressif/common-hal/socketpool/Socket.c
msgid "Cannot set socket options"
@ -759,7 +764,7 @@ msgstr "On ne peut faire de sous-classes de tranches"
#: shared-module/bitbangio/SPI.c
msgid "Cannot transfer without MOSI and MISO pins"
msgstr ""
msgstr "Impossible de transférer sans une broche MOSI ou MISO"
#: shared-bindings/pwmio/PWMOut.c
msgid "Cannot vary frequency on a timer that is already in use"
@ -768,10 +773,13 @@ msgstr "Impossible de faire varier la fréquence sur un minuteur déjà utilisé
#: ports/nrf/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge, only level"
msgstr ""
"Impossible de réveiller via une bordure d'une broche, seulement via un niveau"
#: ports/espressif/common-hal/alarm/pin/PinAlarm.c
msgid "Cannot wake on pin edge. Only level."
msgstr "Ne peut reveillé sur le board de broche. Seuleument à niveau."
msgstr ""
"Impossible de réveiller via une bordure d'une broche. Seulement via un "
"niveau."
#: shared-bindings/_bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
@ -779,7 +787,7 @@ msgstr "Ecriture sur 'CharacteristicBuffer' non fournie"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython core code crashed hard. Whoops!\n"
msgstr "Le code principal de CircuitPython s'est écrasé durement. Oups !\n"
msgstr "Le code principal de CircuitPython s'est complètement planté. Oups !\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap."
@ -958,7 +966,7 @@ msgstr "Echec de l'obtention de mutex, err 0x%04x"
#: shared-module/rgbmatrix/RGBMatrix.c
msgid "Failed to allocate %q buffer"
msgstr ""
msgstr "Échec d'allocation du tampon %q"
#: ports/espressif/common-hal/wifi/__init__.c
msgid "Failed to allocate Wifi memory"
@ -1024,7 +1032,7 @@ msgstr ""
#: shared-bindings/bitmaptools/__init__.c
msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel"
msgstr ""
"Avec l'espace de couleur RGB, l'image d'entrée doit avoir 16 bits par pixel"
"Avec l'espace de couleur RVB, l'image d'entrée doit avoir 16 bits par pixel"
#: ports/cxd56/common-hal/camera/Camera.c
msgid "Format not supported"
@ -1050,7 +1058,7 @@ msgstr "La fonction nécessite un verrou ('lock')"
#: ports/cxd56/common-hal/gnss/GNSS.c
msgid "GNSS init"
msgstr ""
msgstr "Initialisation GNSS"
#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c
msgid "Generic Failure"
@ -1066,8 +1074,9 @@ msgstr "Groupe déjà utilisé"
#: ports/espressif/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/nrf/common-hal/busio/SPI.c
#: ports/raspberrypi/common-hal/busio/SPI.c
#, fuzzy
msgid "Half duplex SPI is not implemented"
msgstr ""
msgstr "Le half duplex du SPI n'est pas implémenté"
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/I2C.c
#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/canio/CAN.c
@ -1085,7 +1094,7 @@ msgstr "Opération d'E/S sur un fichier fermé"
#: ports/stm/common-hal/busio/I2C.c
msgid "I2C init error"
msgstr ""
msgstr "Erreur d'initialisation I2C"
#: ports/raspberrypi/common-hal/busio/I2C.c
msgid "I2C peripheral in use"
@ -1203,6 +1212,11 @@ msgstr "Erreur interne"
msgid "Internal error #%d"
msgstr "Erreur interne #%d"
#: supervisor/shared/safe_mode.c
#, fuzzy
msgid "Internal watchdog timer expired."
msgstr "Le minuteur du watchdog interne a expiré."
#: py/argcheck.c
msgid "Invalid %q"
msgstr "%q invalide"
@ -1288,15 +1302,16 @@ msgstr "Ce calque est déjà dans un groupe"
#: shared-module/displayio/Group.c
msgid "Layer must be a Group or TileGrid subclass"
msgstr ""
msgstr "Le calque doit être une sous-classe de Group ou TileGrid"
#: ports/espressif/bindings/espidf/__init__.c ports/espressif/esp_error.c
msgid "MAC address was invalid"
msgstr "Adresse physique (MAC) invalide"
#: shared-bindings/is31fl3741/IS31FL3741.c
#, fuzzy
msgid "Mapping must be a tuple"
msgstr ""
msgstr "Le mapping doit être un tuple"
#: shared-module/displayio/Shape.c
#, c-format
@ -1310,11 +1325,11 @@ msgstr "Le délais au démarrage du micro doit être entre 0.0 et 1.0"
#: ports/raspberrypi/bindings/rp2pio/StateMachine.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "Mismatched data size"
msgstr ""
msgstr "La taille des données ne correspond pas"
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "Mismatched swap flag"
msgstr ""
msgstr "Le drapeau d'échange ne correspond pas"
#: ports/mimxrt10xx/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
@ -1388,11 +1403,12 @@ msgstr "Nom trop long"
#: shared-bindings/displayio/TileGrid.c
msgid "New bitmap must be same size as old bitmap"
msgstr ""
msgstr "La taille du nouveau bitmap doit être la même que l'ancien"
#: ports/espressif/common-hal/_bleio/__init__.c
#, fuzzy
msgid "Nimble out of memory"
msgstr ""
msgstr "Nimble n'a plus de mémoire"
#: ports/espressif/common-hal/_bleio/Characteristic.c
#: ports/nrf/common-hal/_bleio/Characteristic.c
@ -1422,7 +1438,7 @@ msgstr "Aucun périphérique I2S à l'adresse : 0x%x"
#: supervisor/shared/web_workflow/web_workflow.c
msgid "No IP"
msgstr ""
msgstr "Aucune IP"
#: ports/espressif/common-hal/busio/SPI.c
#: ports/mimxrt10xx/common-hal/busio/SPI.c
@ -1514,7 +1530,7 @@ msgstr "Aucun out dans le programme"
#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nrf/common-hal/busio/I2C.c
#: ports/raspberrypi/common-hal/busio/I2C.c
msgid "No pull up found on SDA or SCL; check your wiring"
msgstr "Aucun pull up trouvé sur SDA ou SCL; vérifiez votre cablage"
msgstr "Aucun pull up trouvé sur SDA ou SCL; vérifiez votre câblage"
#: shared-module/touchio/TouchIn.c
msgid "No pulldown on pin; 1Mohm recommended"
@ -1572,7 +1588,7 @@ msgstr "Le nombre de data_pins doit être 8 ou 16, et non %d"
msgid ""
"Object has been deinitialized and can no longer be used. Create a new object."
msgstr ""
"L'objet a été désinitialisé et ne peut plus être utilisé. Créez un nouvel "
"L'objet a été dés-initialisé et ne peut plus être utilisé. Créez un nouvel "
"objet."
#: ports/nrf/common-hal/busio/UART.c
@ -1623,7 +1639,7 @@ msgstr ""
#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c
msgid "Only one TouchAlarm can be set in deep sleep."
msgstr "Seulement une TouchAlarm peu être réglée en someil profond."
msgstr "Seulement une TouchAlarm peu être réglée en sommeil profond."
#: ports/espressif/common-hal/i2cperipheral/I2CPeripheral.c
msgid "Only one address is allowed"
@ -1633,7 +1649,7 @@ msgstr "Seulement une adresse est autorisée"
#: 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 "Seule une alarme alarm.time peut être définie"
#: ports/espressif/common-hal/alarm/time/TimeAlarm.c
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c
@ -1685,7 +1701,7 @@ msgstr ""
#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "PWM restart"
msgstr ""
msgstr "Redémarrage PWM"
#: ports/raspberrypi/common-hal/countio/Counter.c
msgid "PWM slice already in use"
@ -1773,7 +1789,8 @@ msgstr ""
#: main.c
msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n"
msgstr ""
"Feinte de someil profond jusqu'à l'alarme, CTRL-C ou écriture au fichier.\n"
"Feinte un sommeil profond jusqu'à l'alarme, CTRL-C ou l'écriture d'un "
"fichier.\n"
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "Program does IN without loading ISR"
@ -1811,7 +1828,7 @@ msgstr "Erreur d'initialisation du RNG"
#: 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
@ -1873,7 +1890,7 @@ msgstr "Le format de carte SD CSD n'est pas supporté"
#: ports/cxd56/common-hal/sdioio/SDCard.c
msgid "SDCard init"
msgstr ""
msgstr "Initialisation SDCard"
#: ports/stm/common-hal/sdioio/SDCard.c
#, c-format
@ -1891,7 +1908,7 @@ msgstr "La configuration SPI a échoué"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI init error"
msgstr ""
msgstr "Erreur d'initialisation SPI"
#: ports/raspberrypi/common-hal/busio/SPI.c
msgid "SPI peripheral in use"
@ -1899,7 +1916,7 @@ msgstr "Périphérique SPI utilisé"
#: ports/stm/common-hal/busio/SPI.c
msgid "SPI re-init"
msgstr ""
msgstr "Ré-initialisation du SPI"
#: shared-bindings/is31fl3741/FrameBuffer.c
msgid "Scale dimensions must divide by 3"
@ -2070,7 +2087,7 @@ msgstr "Pour quitter, SVP redémarrez la carte sans "
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample"
msgstr ""
msgstr "Trop de canaux dans l'échantillon"
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample."
@ -2105,20 +2122,20 @@ msgstr "Paramètre de type tuple ou struct_time requis"
#: ports/stm/common-hal/busio/UART.c
msgid "UART de-init"
msgstr ""
msgstr "Dé-initialisation du UART"
#: 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 "Initialisation UART"
#: ports/stm/common-hal/busio/UART.c
msgid "UART re-init"
msgstr ""
msgstr "Ré-initialisation du UART"
#: ports/stm/common-hal/busio/UART.c
msgid "UART write"
msgstr ""
msgstr "Écriture UART"
#: shared-module/usb_hid/Device.c
msgid "USB busy"
@ -2182,7 +2199,7 @@ msgstr "Impossible de lire les données de la palette de couleurs"
#: ports/espressif/common-hal/mdns/Server.c
msgid "Unable to start mDNS query"
msgstr ""
msgstr "Impossible de lancer la requête mDNS"
#: shared-bindings/nvm/ByteArray.c
msgid "Unable to write to nvm."
@ -2204,12 +2221,12 @@ msgstr "Erreur ESP TLS non gérée %d %d %x %d"
#: ports/espressif/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown BLE error at %s:%d: %d"
msgstr ""
msgstr "Erreur BLE inconnue à %s:%d : %d"
#: ports/espressif/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown BLE error: %d"
msgstr ""
msgstr "Erreur BLE inconnue : %d"
#: shared-bindings/wifi/Radio.c
#, c-format
@ -2234,7 +2251,7 @@ msgstr "Erreur de sécurité inconnue : 0x%04x"
#: ports/espressif/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown system firmware error at %s:%d: %d"
msgstr ""
msgstr "Erreur du firmware système inconnue à %s:%d : %d"
#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
@ -2244,7 +2261,7 @@ msgstr "Faute inconnue du logiciel systême : %04x"
#: ports/espressif/common-hal/_bleio/__init__.c
#, c-format
msgid "Unknown system firmware error: %d"
msgstr ""
msgstr "Erreur du firmware système inconnue : %d"
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
#, c-format
@ -2307,7 +2324,7 @@ msgstr "ATTENTION : le nom de fichier de votre code a deux extensions\n"
#: ports/raspberrypi/common-hal/watchdog/WatchDogTimer.c
msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET"
msgstr ""
"WatchDogTimer ne peut pas être désinitialisé une fois que le mode est réglé "
"WatchDogTimer ne peut pas être dés-initialisé une fois que le mode est réglé "
"sur RESET"
#: shared-bindings/watchdog/WatchDogTimer.c
@ -2324,10 +2341,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout doit être supérieur à 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Le minuteur Watchdog a expiré."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -2345,7 +2358,7 @@ msgstr ""
#: supervisor/shared/web_workflow/web_workflow.c
msgid "Wi-Fi: "
msgstr ""
msgstr "Wi-Fi : "
#: main.c
msgid "Woken up by alarm.\n"
@ -2364,8 +2377,8 @@ msgstr "Vous êtres en mode sûr parce que :\n"
msgid ""
"You pressed the reset button during boot. Press again to exit safe mode."
msgstr ""
"Vous avez pressé le bouton de reset pendant le démarrage. Pressez le à "
"nouveau pour sortir du mode sûr."
"Vous avez pressé le bouton reset pendant le démarrage. Pressez-le à nouveau "
"pour sortir du mode sûr."
#: supervisor/shared/safe_mode.c
msgid "You requested starting safe mode by "
@ -2515,7 +2528,7 @@ msgstr "tampon est plus petit que la taille demandée"
#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c
msgid "buffer size must be a multiple of element size"
msgstr "taille du tampon doit être un multiple de la taille de l'élement"
msgstr "taille du tampon doit être un multiple de la taille de lélément"
#: shared-module/struct/__init__.c
msgid "buffer size must match format"
@ -2561,11 +2574,11 @@ msgstr "ne peut avoir qu'un seul parent"
#: py/emitinlinethumb.c
msgid "can only have up to 4 parameters to Thumb assembly"
msgstr "il peut y avoir jusqu'à 4 paramètres pour l'assemblage Thumb"
msgstr "il ne peut pas y avoir plus de 4 paramètres pour l'assemblage Thumb"
#: py/emitinlinextensa.c
msgid "can only have up to 4 parameters to Xtensa assembly"
msgstr "maximum 4 paramètres pour l'assembleur Xtensa"
msgstr "il ne peut pas y avoir plus de 4 paramètres pour l'assemblage Xtensa"
#: py/objtype.c
msgid "can't add special method to already-subclassed class"
@ -2656,7 +2669,7 @@ msgstr "impossible de charger avec l'indice '%q'"
#: py/builtinimport.c
msgid "can't perform relative import"
msgstr ""
msgstr "ne peut importer relativement"
#: py/objgenerator.c
msgid "can't send non-None value to a just-started generator"
@ -2736,7 +2749,7 @@ msgstr "typage"
#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "channel re-init"
msgstr ""
msgstr "Ré-initialisation du canal"
#: shared-bindings/_stage/Text.c
msgid "chars buffer too small"
@ -2769,7 +2782,9 @@ msgstr ""
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a bytearray or array of type 'b' or 'B'"
msgstr "tampon color doit être un bytearray ou une matrice de type 'b' ou 'B'"
msgstr ""
"le tampon de couleurs doit être un bytearray ou une matrice de type 'b' ou "
"'B'"
#: shared-bindings/displayio/Palette.c
msgid "color must be between 0x000000 and 0xffffff"
@ -3079,7 +3094,7 @@ msgstr "fonction définie que pour les ndarrays"
#: extmod/ulab/code/numpy/carray/carray.c
msgid "function is implemented for ndarrays only"
msgstr ""
msgstr "la fonction n'est implémentée que pour les ndarrays"
#: py/argcheck.c
#, c-format
@ -3181,7 +3196,7 @@ msgstr ""
#: ports/espressif/common-hal/busio/I2C.c
msgid "init I2C"
msgstr ""
msgstr "initialisation I2C"
#: extmod/ulab/code/scipy/optimize/optimize.c
msgid "initial values must be iterable"
@ -3217,7 +3232,7 @@ msgstr "les données d'entrée doivent être un itérable"
#: extmod/ulab/code/numpy/vector.c
msgid "input dtype must be float or complex"
msgstr ""
msgstr "le dtype d'entrée doit être un flottant ou un complexe"
#: extmod/ulab/code/numpy/linalg/linalg.c
msgid "input matrix is asymmetric"
@ -3246,7 +3261,7 @@ msgstr "l'entrée doit être un ndarray"
#: extmod/ulab/code/numpy/carray/carray.c
msgid "input must be an ndarray, or a scalar"
msgstr ""
msgstr "l'entrée doit être un ndarray, ou un scalaire"
#: extmod/ulab/code/scipy/signal/signal.c
msgid "input must be one-dimensional"
@ -3270,7 +3285,7 @@ msgstr "les entrées ne sont pas itérables"
#: py/parsenum.c
msgid "int() arg 2 must be >= 2 and <= 36"
msgstr "l'argument 2 de int() doit être >=2 et <=36"
msgstr "Le deuxième argument de int() doit être compris entre 2 et 36 inclus"
#: extmod/ulab/code/numpy/approx.c
msgid "interp is defined for 1D iterables of equal length"
@ -3353,7 +3368,8 @@ msgstr "l'argument 1 de issubclass() doit être une classe"
#: py/objtype.c
msgid "issubclass() arg 2 must be a class or a tuple of classes"
msgstr ""
"l'argument 2 de issubclass() doit être une classe ou un tuple de classes"
"le deuxième argument de issubclass() doit être une classe ou un tuple de "
"classes"
#: extmod/ulab/code/numpy/linalg/linalg.c
msgid "iterations did not converge"
@ -3416,11 +3432,11 @@ msgstr "loopback + silent mode non pris en charge par le périphérique"
#: ports/espressif/common-hal/mdns/Server.c
msgid "mDNS already initialized"
msgstr ""
msgstr "mDNS a déjà été initialisé"
#: ports/espressif/common-hal/mdns/Server.c
msgid "mDNS only works with built-in WiFi"
msgstr ""
msgstr "mDNS ne fonctionne que avec le WiFi intégré"
#: py/parse.c
msgid "malformed f-string"
@ -3695,7 +3711,7 @@ msgstr "chaîne de longueur impaire"
#: supervisor/shared/web_workflow/web_workflow.c
msgid "off"
msgstr ""
msgstr "inactif"
#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c
msgid "offset is too large"
@ -3707,7 +3723,8 @@ msgstr "offset doit être >= 0"
#: extmod/ulab/code/numpy/create.c
msgid "offset must be non-negative and no greater than buffer length"
msgstr "offset doit être non-négatif, et au plus la taille du tampon"
msgstr ""
"offset ne doit pas être négatif, et pas plus grand que la taille du tampon"
#: py/objstr.c py/objstrunicode.c
msgid "offset out of bounds"
@ -3763,8 +3780,7 @@ msgstr "ord attend un caractère"
#, c-format
msgid "ord() expected a character, but string of length %d found"
msgstr ""
"ord() attend un caractère mais une chaîne de caractère de longueur %d a été "
"trouvée"
"ord() attend un caractère mais une chaîne de %d caractères a été trouvée"
#: extmod/ulab/code/utils/utils.c
msgid "out array is too small"
@ -3822,7 +3838,7 @@ msgstr ""
#: extmod/vfs_posix_file.c
msgid "poll on file not available on win32"
msgstr ""
msgstr "le polling sur un fichier n'est pas disponible sous win32"
#: ports/espressif/common-hal/pulseio/PulseIn.c
msgid "pop from an empty PulseIn"
@ -4026,10 +4042,6 @@ msgstr "source_bitmap doit avoir une value_count de 65536"
msgid "source_bitmap must have value_count of 8"
msgstr "source_bitmap doit avoir une value_count de 8"
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr "un ssid ne peut pas faire plus de 32 octets"
#: py/objstr.c
msgid "start/end indices"
msgstr "indices de début/fin"
@ -4120,7 +4132,7 @@ msgstr "Délai dexpiration dépassé en attendant une carte v2"
#: ports/stm/common-hal/pwmio/PWMOut.c
msgid "timer re-init"
msgstr ""
msgstr "Ré-initialisation du miniteur"
#: shared-bindings/time/__init__.c
msgid "timestamp out of range for platform time_t"
@ -4339,7 +4351,7 @@ msgstr "type d'entrée incorrect"
#: extmod/ulab/code/numpy/transform.c
msgid "wrong length of condition array"
msgstr ""
msgstr "mauvaise taille du tableau de condition"
#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c
msgid "wrong number of arguments"
@ -4385,6 +4397,12 @@ msgstr "zi doit être de type float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi doit être de forme (n_section, 2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "Le minuteur Watchdog a expiré."
#~ msgid "ssid can't be more than 32 bytes"
#~ msgstr "un ssid ne peut pas faire plus de 32 octets"
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q doit être un tuple de longueur 2"

View File

@ -72,7 +72,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -432,7 +432,6 @@ msgstr ""
msgid "All event channels in use"
msgstr ""
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -518,7 +517,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1160,6 +1159,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2244,10 +2247,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3915,10 +3914,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -79,7 +79,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -442,7 +442,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "Tutti i canali eventi utilizati"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Tutte le state machines sono in uso"
@ -528,7 +527,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Autenticazione Fallita"
@ -1178,6 +1177,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2274,10 +2277,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3969,10 +3968,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -77,7 +77,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -437,7 +437,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "全てのイベントチャネルが使用中"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -523,7 +522,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "認証失敗"
@ -1171,6 +1170,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "内部エラー #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "不正な %q"
@ -2258,10 +2261,6 @@ msgstr "WatchDogTimer.modeはいったんWatchDogMode.RESETに設定すると変
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeoutは0以上でなければなりません"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3937,10 +3936,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -73,7 +73,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -433,7 +433,6 @@ msgstr ""
msgid "All event channels in use"
msgstr ""
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -519,7 +518,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr ""
@ -1163,6 +1162,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2248,10 +2251,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3919,10 +3918,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -75,7 +75,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -435,7 +435,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "Alle event kanalen zijn in gebruik"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -521,7 +520,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Authenticatiefout"
@ -1171,6 +1170,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "Interne fout #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Ongeldige %q"
@ -2274,10 +2277,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout moet groter dan 0 zijn"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Watchdog-timer verstreken."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3954,10 +3953,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr "start/stop indices"
@ -4312,6 +4307,9 @@ msgstr "zi moet van type float zijn"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi moet vorm (n_section, 2) hebben"
#~ msgid "Watchdog timer expired."
#~ msgstr "Watchdog-timer verstreken."
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q moet een tuple van lengte 2 zijn"

View File

@ -77,7 +77,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -437,7 +437,6 @@ msgstr ""
msgid "All event channels in use"
msgstr "Wszystkie kanały zdarzeń w użyciu"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr ""
@ -523,7 +522,7 @@ msgstr ""
msgid "AuthMode.OPEN is not used with password"
msgstr ""
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Błąd autoryzacji"
@ -1171,6 +1170,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr "Błąd wewnętrzny #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Nieprawidłowe %q"
@ -2255,10 +2258,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout musi być większe od 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3929,10 +3928,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr "początkowe/końcowe indeksy"

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-06-16 08:18+0000\n"
"PO-Revision-Date: 2022-07-03 00:22+0000\n"
"Last-Translator: Wellington Terumi Uemura <wellingtonuemura@gmail.com>\n"
"Language-Team: \n"
"Language: pt_BR\n"
@ -14,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.13-dev\n"
"X-Generator: Weblate 4.13.1-dev\n"
#: main.c
msgid ""
@ -81,7 +81,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr "%q"
@ -445,7 +445,6 @@ msgstr "Todos os canais estão em uso"
msgid "All event channels in use"
msgstr "Todos os canais de eventos em uso"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "O estado de todas as máquinas em uso"
@ -532,7 +531,7 @@ msgstr "A conversão de áudio ainda não foi implementada"
msgid "AuthMode.OPEN is not used with password"
msgstr "O AuthMode.OPEN não é usado com senha"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Houve um falha na autenticação"
@ -1199,6 +1198,10 @@ msgstr "Erro interno"
msgid "Internal error #%d"
msgstr "Erro interno #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr "O temporizador do watchdog interno expirou."
#: py/argcheck.c
msgid "Invalid %q"
msgstr "%q Inválido"
@ -2320,10 +2323,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "O WatchDogTimer.timeout deve ser maior que 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "O temporizador Watchdog expirou."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -4020,10 +4019,6 @@ msgstr "o source_bitmap deve ter o value_count de 65536"
msgid "source_bitmap must have value_count of 8"
msgstr "o source_bitmap deve ter o value_count de 8"
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr "O ssid não pode ter mais do que 32 bytes"
#: py/objstr.c
msgid "start/end indices"
msgstr "os índices de início/fim"
@ -4378,6 +4373,12 @@ msgstr "zi deve ser de um tipo float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi deve estar na forma (n_section, 2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "O temporizador Watchdog expirou."
#~ msgid "ssid can't be more than 32 bytes"
#~ msgstr "O ssid não pode ter mais do que 32 bytes"
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q deve ser uma tupla de comprimento 2"

View File

@ -80,7 +80,7 @@ msgstr "%d адресные пины, %d rgb пины и %d плитки ука
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -440,7 +440,6 @@ msgstr "Все каналы уже используются"
msgid "All event channels in use"
msgstr "Все каналы событий уже используются"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Все машины состояний уже используются"
@ -526,7 +525,7 @@ msgstr "Преобразование звука не реализовано"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN не используется с паролем"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Ошибка аутентификации"
@ -1196,6 +1195,10 @@ msgstr "Внутренняя ошибка"
msgid "Internal error #%d"
msgstr "Внутренняя ошибка #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Недопустимый %q"
@ -2293,10 +2296,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3964,10 +3963,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

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-06-16 08:18+0000\n"
"PO-Revision-Date: 2022-07-01 17:46+0000\n"
"Last-Translator: Jonny Bergdahl <jonny@bergdahl.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: sv\n"
@ -14,7 +14,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.13-dev\n"
"X-Generator: Weblate 4.13.1-dev\n"
#: main.c
msgid ""
@ -80,7 +80,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr "%q"
@ -440,7 +440,6 @@ msgstr "Alla kanaler används"
msgid "All event channels in use"
msgstr "Alla händelsekanaler används"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Alla tillståndsmaskiner används"
@ -526,7 +525,7 @@ msgstr "Ljudkonvertering inte implementerad"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN används inte med lösenord"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Autentiseringsfel"
@ -1180,6 +1179,10 @@ msgstr "Internt fel"
msgid "Internal error #%d"
msgstr "Internt fel #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr "Intern watchdog-timer har löpt ut."
#: py/argcheck.c
msgid "Invalid %q"
msgstr "Ogiltig %q"
@ -2290,10 +2293,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.timeout måste vara större än 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Watchdog-timern har löpt ut."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3979,10 +3978,6 @@ msgstr "source_bitmap måste ha value_count av 65536"
msgid "source_bitmap must have value_count of 8"
msgstr "source_bitmap måste ha value_count av 8"
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr "ssid kan vara max 32 bytes"
#: py/objstr.c
msgid "start/end indices"
msgstr "start-/slutindex"
@ -4337,6 +4332,12 @@ msgstr "zi måste vara av typ float"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi måste vara i formen (n_section, 2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "Watchdog-timern har löpt ut."
#~ msgid "ssid can't be more than 32 bytes"
#~ msgstr "ssid kan vara max 32 bytes"
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q måste vara en tuple av längd 2"

View File

@ -84,7 +84,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -446,7 +446,6 @@ msgstr "Tüm kanallar kullanımda"
msgid "All event channels in use"
msgstr "Tüm olay kanalları kullanımda"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "Tüm durum makineleri kullanımda"
@ -532,7 +531,7 @@ msgstr "Ses dönüşümü implemente edilmedi"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN bir şifre ile kullanılmadı"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "Kimlik doğrulama hatası"
@ -1177,6 +1176,10 @@ msgstr ""
msgid "Internal error #%d"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr ""
@ -2264,10 +2267,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr ""
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3935,10 +3934,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr ""
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr ""
#: py/objstr.c
msgid "start/end indices"
msgstr ""

View File

@ -83,7 +83,7 @@ msgstr ""
#: ports/mimxrt10xx/common-hal/rtc/RTC.c
#: ports/nrf/common-hal/analogio/AnalogOut.c ports/nrf/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/analogio/AnalogOut.c
#: ports/raspberrypi/common-hal/rtc/RTC.c
#: ports/raspberrypi/common-hal/rtc/RTC.c ports/stm/common-hal/rtc/RTC.c
msgid "%q"
msgstr ""
@ -443,7 +443,6 @@ msgstr "suǒyǒu píndào dōu zài shǐyòng zhōng"
msgid "All event channels in use"
msgstr "suǒyǒu shìjiàn píndào dōu zài shǐyòng zhōng"
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "All state machines in use"
msgstr "suǒyǒu zhuàngtàijī dōu zài shǐyòng zhōng"
@ -530,7 +529,7 @@ msgstr "yīnpín zhuǎnhuàn wèi bèi shíxiàn"
msgid "AuthMode.OPEN is not used with password"
msgstr "AuthMode.OPEN wèi shǐyòng mìmǎ"
#: shared-bindings/wifi/Radio.c
#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c
msgid "Authentication failure"
msgstr "shēnfèn ren4zheng4 shībài"
@ -1194,6 +1193,10 @@ msgstr "nèi bù cuò wù"
msgid "Internal error #%d"
msgstr "nèi bù cuò wù #%d"
#: supervisor/shared/safe_mode.c
msgid "Internal watchdog timer expired."
msgstr ""
#: py/argcheck.c
msgid "Invalid %q"
msgstr "wú xiào %q"
@ -2301,10 +2304,6 @@ msgstr ""
msgid "WatchDogTimer.timeout must be greater than 0"
msgstr "WatchDogTimer.Timeout bìxū dàyú 0"
#: supervisor/shared/safe_mode.c
msgid "Watchdog timer expired."
msgstr "Kān mén gǒu dìngshí qì yǐ guòqí."
#: py/builtinhelp.c
#, c-format
msgid ""
@ -3991,10 +3990,6 @@ msgstr ""
msgid "source_bitmap must have value_count of 8"
msgstr "yuán wèi tú (source_bitmap) de zhí de shù mù (value_count) bì xū shì 8"
#: shared-bindings/wifi/Radio.c
msgid "ssid can't be more than 32 bytes"
msgstr "ssid bù néng chāo guò 32 gè zì jié"
#: py/objstr.c
msgid "start/end indices"
msgstr "kāishǐ/jiéshù zhǐshù"
@ -4349,6 +4344,12 @@ msgstr "zi bìxū wèi fú diǎn xíng"
msgid "zi must be of shape (n_section, 2)"
msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)"
#~ msgid "Watchdog timer expired."
#~ msgstr "Kān mén gǒu dìngshí qì yǐ guòqí."
#~ msgid "ssid can't be more than 32 bytes"
#~ msgstr "ssid bù néng chāo guò 32 gè zì jié"
#~ msgid "%q must be a tuple of length 2"
#~ msgstr "%q bìxū shì chángdù wèi 2 de yuánzǔ"

3
main.c
View File

@ -587,6 +587,9 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
else if (awoke_from_true_deep_sleep ||
port_get_raw_ticks(NULL) > CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY * 1024) {
// OK to start sleeping, real or fake.
#if CIRCUITPY_DISPLAYIO
common_hal_displayio_release_displays();
#endif
status_led_deinit();
deinit_rxtx_leds();
board_deinit();

View File

@ -17,7 +17,6 @@ CIRCUITPY_ONEWIREIO = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_SDCARDIO = 0
CIRCUITPY_SHARPDISPLAY = 0
CIRCUITPY_TRACEBACK = 0
CIRCUITPY_ZLIB=0
# Include these Python libraries in firmware.

View File

@ -40,6 +40,9 @@
#include "common-hal/pulseio/PulseIn.h"
#endif
#if CIRCUITPY_WEB_WORKFLOW
#include "supervisor/shared/web_workflow/web_workflow.h"
#endif
void port_background_task(void) {
// Zero delay in case FreeRTOS wants to switch to something else.
@ -47,6 +50,10 @@ void port_background_task(void) {
#if CIRCUITPY_PULSEIO
pulsein_background();
#endif
#if CIRCUITPY_WEB_WORKFLOW
supervisor_web_workflow_background();
#endif
}
void port_start_background_task(void) {

View File

@ -13,5 +13,5 @@ LONGINT_IMPL = MPZ
CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32
CIRCUITPY_ESP_FLASH_MODE = dio
CIRCUITPY_ESP_FLASH_FREQ = 80m
CIRCUITPY_ESP_FLASH_FREQ = 40m
CIRCUITPY_ESP_FLASH_SIZE = 16MB

View File

@ -0,0 +1,47 @@
/*
* 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 "shared-bindings/microcontroller/Pin.h"
#include "supervisor/board.h"
#include "components/driver/include/driver/gpio.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
return false;
}
void reset_board(void) {
}
void board_deinit(void) {
}

View File

@ -0,0 +1,51 @@
/*
* 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.
*/
// Board setup
#define MICROPY_HW_BOARD_NAME "Wemos Lolin C3 Mini" // from Wemos MP
#define MICROPY_HW_MCU_NAME "ESP32-C3FH4" // from Wemos MP
// From Wemos C3 Mini Schematic
// https://www.wemos.cc/en/latest/_static/files/sch_c3_mini_v1.0.0.pdf
// And MP Config
// https://github.com/micropython/micropython/blob/master/ports/esp32/boards/LOLIN_C3_MINI
// Status LED
#define MICROPY_HW_NEOPIXEL (&pin_GPIO7)
#define CIRCUITPY_BOARD_I2C (1)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO6, .sda = &pin_GPIO5}}
#define CIRCUITPY_BOARD_SPI (1)
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO10, .mosi = &pin_GPIO7, .miso = &pin_GPIO8}}
#define CIRCUITPY_BOARD_UART (1)
#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}}
// Explanation of how a user got into safe mode
#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n")
#define CIRCUITPY_ESP_USB_SERIAL_JTAG (1)

View File

@ -0,0 +1,10 @@
CIRCUITPY_CREATOR_ID = 0x19881988
CIRCUITPY_CREATION_ID = 0x00C30001
IDF_TARGET = esp32c3
INTERNAL_FLASH_FILESYSTEM = 1
CIRCUITPY_ESP_FLASH_MODE=qio
CIRCUITPY_ESP_FLASH_FREQ=80m
CIRCUITPY_ESP_FLASH_SIZE=4MB

View File

@ -0,0 +1,74 @@
#include "shared-bindings/board/__init__.h"
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
// C3 Mini Board
// Wemos Lolin C3 Mini Schematic
// https://www.wemos.cc/en/latest/_static/files/sch_c3_mini_v1.0.0.pdf
// Starting on Left side going counterclockwise
// MP Config
// https://github.com/micropython/micropython/blob/master/ports/esp32/boards/LOLIN_C3_MINI
// C3 Data Sheet
// https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -0,0 +1,7 @@
#
# LWIP
#
CONFIG_LWIP_LOCAL_HOSTNAME="lolin-c3-mini"
# end of LWIP

View File

@ -26,6 +26,8 @@
#include "shared-bindings/mdns/RemoteService.h"
#include "shared-bindings/ipaddress/IPv4Address.h"
const char *common_hal_mdns_remoteservice_get_service_type(mdns_remoteservice_obj_t *self) {
if (self->result == NULL) {
return "";
@ -61,6 +63,32 @@ mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self)
return self->result->port;
}
uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) {
if (self->result == NULL ||
self->result->ip_protocol != MDNS_IP_PROTOCOL_V4 ||
self->result->addr == NULL) {
return 0;
}
mdns_ip_addr_t *cur = self->result->addr;
while (cur != NULL) {
if (cur->addr.type == ESP_IPADDR_TYPE_V4) {
return cur->addr.u_addr.ip4.addr;
}
cur = cur->next;
}
return 0;
}
mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) {
uint32_t addr = mdns_remoteservice_get_ipv4_address(self);
if (addr == 0) {
return mp_const_none;
}
return common_hal_ipaddress_new_ipv4address(addr);
}
void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self) {
mdns_query_results_free(self->result);
self->result = NULL;

View File

@ -35,13 +35,9 @@
STATIC bool inited = false;
void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_interface) {
if (network_interface != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) {
mp_raise_ValueError(translate("mDNS only works with built-in WiFi"));
return;
}
void mdns_server_construct(mdns_server_obj_t *self, bool workflow) {
if (inited) {
mp_raise_RuntimeError(translate("mDNS already initialized"));
return;
}
mdns_init();
@ -50,19 +46,31 @@ void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_
snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]);
common_hal_mdns_server_set_hostname(self, self->default_hostname);
// Set a delegated entry to ourselves. This allows us to respond to "circuitpython.local"
// queries as well.
// TODO: Allow for disabling this with `supervisor.disable_web_workflow()`.
mdns_ip_addr_t our_ip;
esp_netif_get_ip_info(common_hal_wifi_radio_obj.netif, &common_hal_wifi_radio_obj.ip_info);
our_ip.next = NULL;
our_ip.addr.type = ESP_IPADDR_TYPE_V4;
our_ip.addr.u_addr.ip4 = common_hal_wifi_radio_obj.ip_info.ip;
our_ip.addr.u_addr.ip6.addr[1] = 0;
our_ip.addr.u_addr.ip6.addr[2] = 0;
our_ip.addr.u_addr.ip6.addr[3] = 0;
our_ip.addr.u_addr.ip6.zone = 0;
mdns_delegate_hostname_add("circuitpython", &our_ip);
if (workflow) {
// Set a delegated entry to ourselves. This allows us to respond to "circuitpython.local"
// queries as well.
mdns_ip_addr_t our_ip;
esp_netif_get_ip_info(common_hal_wifi_radio_obj.netif, &common_hal_wifi_radio_obj.ip_info);
our_ip.next = NULL;
our_ip.addr.type = ESP_IPADDR_TYPE_V4;
our_ip.addr.u_addr.ip4 = common_hal_wifi_radio_obj.ip_info.ip;
our_ip.addr.u_addr.ip6.addr[1] = 0;
our_ip.addr.u_addr.ip6.addr[2] = 0;
our_ip.addr.u_addr.ip6.addr[3] = 0;
our_ip.addr.u_addr.ip6.zone = 0;
mdns_delegate_hostname_add("circuitpython", &our_ip);
}
}
void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_interface) {
if (network_interface != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) {
mp_raise_ValueError(translate("mDNS only works with built-in WiFi"));
return;
}
if (inited) {
mp_raise_RuntimeError(translate("mDNS already initialized"));
}
mdns_server_construct(self, false);
}
void common_hal_mdns_server_deinit(mdns_server_obj_t *self) {
@ -97,6 +105,48 @@ void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const cha
self->instance_name = instance_name;
}
size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol,
mp_float_t timeout, mdns_remoteservice_obj_t *out, size_t out_len) {
mdns_search_once_t *search = mdns_query_async_new(NULL, service_type, protocol, MDNS_TYPE_PTR, timeout * 1000, 255, NULL);
if (search == NULL) {
return 0;
}
mdns_result_t *results;
while (!mdns_query_async_get_results(search, 1, &results)) {
RUN_BACKGROUND_TASKS;
}
mdns_query_async_delete(search);
// Count how many results we got.
// TODO: Remove this loop when moving off 4.4. Newer APIs will give us num_results
// back directly.
mdns_result_t *next = results;
uint8_t num_results = 0;
while (next != NULL) {
num_results++;
next = next->next;
}
next = results;
// Don't error if we're out of memory. Instead, truncate the tuple.
uint8_t added = 0;
while (next != NULL && added < out_len) {
mdns_remoteservice_obj_t *service = &out[added];
service->result = next;
service->base.type = &mdns_remoteservice_type;
next = next->next;
// Break the linked list so we free each result separately.
service->result->next = NULL;
added++;
}
if (added < out_len) {
// Free the remaining results from the IDF because we don't have
// enough space in Python.
mdns_query_results_free(next);
}
return num_results;
}
mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_float_t timeout) {
mdns_search_once_t *search = mdns_query_async_new(NULL, service_type, protocol, MDNS_TYPE_PTR, timeout * 1000, 255, NULL);
if (search == NULL) {

View File

@ -69,6 +69,7 @@ volatile uint32_t nesting_count = 0;
static portMUX_TYPE cp_mutex = portMUX_INITIALIZER_UNLOCKED;
void common_hal_mcu_disable_interrupts(void) {
assert(xPortGetCoreID() == CONFIG_ESP_MAIN_TASK_AFFINITY);
if (nesting_count == 0) {
portENTER_CRITICAL(&cp_mutex);
}
@ -76,9 +77,8 @@ void common_hal_mcu_disable_interrupts(void) {
}
void common_hal_mcu_enable_interrupts(void) {
if (nesting_count == 0) {
// Maybe log here because it's very bad.
}
assert(xPortGetCoreID() == CONFIG_ESP_MAIN_TASK_AFFINITY);
assert(nesting_count > 0);
nesting_count--;
if (nesting_count > 0) {
return;

View File

@ -62,8 +62,7 @@ bool register_open_socket(socketpool_socket_obj_t *self) {
return false;
}
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
uint8_t *ip, uint32_t *port) {
int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port) {
struct sockaddr_in accept_addr;
socklen_t socklen = sizeof(accept_addr);
int newsoc = -1;
@ -71,17 +70,15 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
uint64_t start_ticks = supervisor_ticks_ms64();
// Allow timeouts and interrupts
while (newsoc == -1 &&
!timed_out &&
!mp_hal_is_interrupted()) {
while (newsoc == -1 && !timed_out) {
if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) {
timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
}
RUN_BACKGROUND_TASKS;
newsoc = lwip_accept(self->num, (struct sockaddr *)&accept_addr, &socklen);
// In non-blocking mode, fail instead of timing out
if (newsoc == -1 && self->timeout_ms == 0) {
mp_raise_OSError(MP_EAGAIN);
if (newsoc == -1 && (self->timeout_ms == 0 || mp_hal_is_interrupted())) {
return -MP_EAGAIN;
}
}
@ -90,8 +87,17 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
memcpy((void *)ip, (void *)&accept_addr.sin_addr.s_addr, sizeof(accept_addr.sin_addr.s_addr));
*port = accept_addr.sin_port;
} else {
mp_raise_OSError(ETIMEDOUT);
return -ETIMEDOUT;
}
if (newsoc < 0) {
return -MP_EBADF;
}
return newsoc;
}
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self,
uint8_t *ip, uint32_t *port) {
int newsoc = socketpool_socket_accept(self, ip, port);
if (newsoc > 0) {
// Create the socket
@ -108,7 +114,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
lwip_fcntl(newsoc, F_SETFL, O_NONBLOCK);
return sock;
} else {
mp_raise_OSError(MP_EBADF);
mp_raise_OSError(-newsoc);
return NULL;
}
}
@ -116,7 +122,17 @@ socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_o
bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self,
const char *host, size_t hostlen, uint32_t port) {
struct sockaddr_in bind_addr;
bind_addr.sin_addr.s_addr = inet_addr(host);
const char *broadcast = "<broadcast>";
uint32_t ip;
if (hostlen == 0) {
ip = IPADDR_ANY;
} else if (hostlen == strlen(broadcast) &&
memcmp(host, broadcast, strlen(broadcast)) == 0) {
ip = IPADDR_BROADCAST;
} else {
ip = inet_addr(host);
}
bind_addr.sin_addr.s_addr = ip;
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(port);
@ -125,17 +141,21 @@ bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self,
if (err != 0) {
mp_raise_RuntimeError(translate("Cannot set socket options"));
}
int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) == 0;
return result;
int result = lwip_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
return result == 0;
}
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
void socketpool_socket_close(socketpool_socket_obj_t *self) {
self->connected = false;
if (self->num >= 0) {
lwip_shutdown(self->num, 0);
lwip_shutdown(self->num, SHUT_RDWR);
lwip_close(self->num);
self->num = -1;
}
}
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
socketpool_socket_close(self);
// Remove socket record
for (size_t i = 0; i < MP_ARRAY_SIZE(open_socket_handles); i++) {
if (open_socket_handles[i] == self) {
@ -199,7 +219,7 @@ bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self) {
}
bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) {
return lwip_listen(self->num, backlog) == 0;
return lwip_listen(self->num, backlog);
}
mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self,
@ -242,7 +262,8 @@ mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *se
return received;
}
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
const uint8_t *buf, uint32_t len) {
int received = 0;
bool timed_out = false;
@ -251,8 +272,7 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self,
uint64_t start_ticks = supervisor_ticks_ms64();
received = -1;
while (received == -1 &&
!timed_out &&
!mp_hal_is_interrupted()) {
!timed_out) {
if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) {
timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms;
}
@ -261,31 +281,64 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self,
// In non-blocking mode, fail instead of looping
if (received == -1 && self->timeout_ms == 0) {
mp_raise_OSError(MP_EAGAIN);
if (errno == ENOTCONN) {
self->connected = false;
return -MP_ENOTCONN;
}
return -MP_EAGAIN;
}
// Check this after going through the loop once so it can make
// progress while interrupted.
if (mp_hal_is_interrupted()) {
if (received == -1) {
return -MP_EAGAIN;
}
break;
}
}
} else {
mp_raise_OSError(MP_EBADF);
return -MP_EBADF;
}
if (timed_out) {
mp_raise_OSError(ETIMEDOUT);
return -ETIMEDOUT;
}
return received;
}
mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
int received = socketpool_socket_recv_into(self, buf, len);
if (received < 0) {
mp_raise_OSError(received);
}
return received;
}
int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
int sent = -1;
if (self->num != -1) {
// LWIP Socket
// TODO: deal with potential failure/add timeout?
sent = lwip_send(self->num, buf, len, 0);
} else {
mp_raise_OSError(MP_EBADF);
sent = -MP_EBADF;
}
if (sent < 0) {
mp_raise_OSError(errno);
if (errno == ECONNRESET || errno == ENOTCONN) {
self->connected = false;
}
return -errno;
}
return sent;
}
mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
int sent = socketpool_socket_send(self, buf, len);
if (sent < 0) {
mp_raise_OSError(-sent);
}
return sent;
}

View File

@ -40,9 +40,9 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *sel
}
}
socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self,
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) {
bool socketpool_socket(socketpool_socketpool_obj_t *self,
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type,
socketpool_socket_obj_t *sock) {
int addr_family;
int ipproto;
if (family == SOCKETPOOL_AF_INET) {
@ -61,13 +61,6 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
} else { // SOCKETPOOL_SOCK_RAW
socket_type = SOCK_RAW;
}
if (addr_family == AF_INET6 || ipproto == IPPROTO_IPV6) {
mp_raise_NotImplementedError(translate("Only IPv4 sockets supported"));
}
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
sock->base.type = &socketpool_socket_type;
sock->type = socket_type;
sock->family = addr_family;
sock->ipproto = ipproto;
@ -77,12 +70,28 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
// Create LWIP socket
int socknum = -1;
socknum = lwip_socket(sock->family, sock->type, sock->ipproto);
if (socknum < 0 || !register_open_socket(sock)) {
mp_raise_RuntimeError(translate("Out of sockets"));
if (socknum < 0) {
return false;
}
sock->num = socknum;
// Sockets should be nonblocking in most cases
lwip_fcntl(socknum, F_SETFL, O_NONBLOCK);
return true;
}
socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self,
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type) {
if (family != SOCKETPOOL_AF_INET) {
mp_raise_NotImplementedError(translate("Only IPv4 sockets supported"));
}
socketpool_socket_obj_t *sock = m_new_obj_with_finaliser(socketpool_socket_obj_t);
sock->base.type = &socketpool_socket_type;
if (!socketpool_socket(self, family, type, sock) ||
!register_open_socket(sock)) {
mp_raise_RuntimeError(translate("Out of sockets"));
}
return sock;
}

View File

@ -139,6 +139,16 @@ void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t
esp_wifi_set_mac(ESP_IF_WIFI_STA, mac);
}
uint8_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self) {
int8_t tx_power;
esp_wifi_get_max_tx_power(&tx_power);
return tx_power / 4;
}
void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const uint8_t tx_power) {
esp_wifi_set_max_tx_power(tx_power * 4);
}
mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) {
uint8_t mac[MAC_ADDRESS_LENGTH];
esp_wifi_get_mac(ESP_IF_WIFI_AP, mac);
@ -318,6 +328,7 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t
self->retries_left = 0;
}
} while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted());
if ((bits & WIFI_DISCONNECTED_BIT) != 0) {
if (self->last_disconnect_reason == WIFI_REASON_AUTH_FAIL) {
return WIFI_RADIO_ERROR_AUTH_FAIL;

View File

@ -42,12 +42,25 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
#include "components/log/include/esp_log.h"
#include "supervisor/port.h"
#include "supervisor/workflow.h"
static const char *TAG = "wifi";
#include "esp_ipc.h"
static const char *TAG = "CP wifi";
STATIC void schedule_background_on_cp_core(void *arg) {
supervisor_workflow_request_background();
// CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to
// notify the main task every time in case it's waiting for us.
port_wake_main_task();
}
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
// This runs on the PRO CORE! It cannot share CP interrupt enable/disable
// directly.
wifi_radio_obj_t *radio = arg;
if (event_base == WIFI_EVENT) {
switch (event_id) {
@ -108,7 +121,14 @@ static void event_handler(void *arg, esp_event_base_t event_base,
radio->retries_left = radio->starting_retries;
xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT);
}
supervisor_workflow_request_background();
// Use IPC to ensure we run schedule background on the same core as CircuitPython.
#if defined(CONFIG_FREERTOS_UNICORE) && CONFIG_FREERTOS_UNICORE
schedule_background_on_cp_core(NULL);
#else
// This only blocks until the start of the function. That's ok since the PRO
// core shouldn't care what we do.
esp_ipc_call(CONFIG_ESP_MAIN_TASK_AFFINITY, schedule_background_on_cp_core, NULL);
#endif
}
static bool wifi_inited;

@ -1 +1 @@
Subproject commit 944c01eef4fbba693f991f9d033cda3f59ca82c9
Subproject commit 171e5af9c5b9b126c5f81f217c7b1ff931d54863

View File

@ -805,9 +805,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y
CONFIG_LOG_BOOTLOADER_LEVEL=3
# CONFIG_APP_ROLLBACK_ENABLE is not set
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
# CONFIG_FLASHMODE_QIO is not set
CONFIG_FLASHMODE_QIO=y
# CONFIG_FLASHMODE_QOUT is not set
CONFIG_FLASHMODE_DIO=y
# CONFIG_FLASHMODE_DIO is not set
# CONFIG_FLASHMODE_DOUT is not set
# CONFIG_MONITOR_BAUD_9600B is not set
# CONFIG_MONITOR_BAUD_57600B is not set

View File

@ -26,8 +26,26 @@
#include "py/runtime.h"
#include "lib/oofatfs/ff.h"
#include "shared/timeutils/timeutils.h"
#include "shared-bindings/rtc/RTC.h"
#include "shared-bindings/time/__init__.h"
#include "supervisor/fatfs_port.h"
DWORD _time_override = 0;
DWORD get_fattime(void) {
// TODO: Implement this function. For now, fake it.
return ((2016 - 1980) << 25) | ((12) << 21) | ((4) << 16) | ((00) << 11) | ((18) << 5) | (23 / 2);
if (_time_override > 0) {
return _time_override;
}
#if CIRCUITPY_RTC
timeutils_struct_time_t tm;
common_hal_rtc_get_time(&tm);
return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) |
(tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1);
#else
return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2);
#endif
}
void override_fattime(DWORD time) {
_time_override = time;
}

View File

@ -230,6 +230,9 @@ safe_mode_t port_init(void) {
case ESP_RST_PANIC:
return HARD_CRASH;
case ESP_RST_INT_WDT:
// The interrupt watchdog is used internally to make sure that latency sensitive
// interrupt code isn't blocked. User watchdog resets come through ESP_RST_WDT.
return WATCHDOG_RESET;
case ESP_RST_WDT:
default:
break;

View File

@ -9,3 +9,11 @@ CHIP_FAMILY = rp2
EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ"
CIRCUITPY__EVE = 1
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_asyncio
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IS31FL3731
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Ticks
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_ef_music
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_picoed

View File

@ -436,7 +436,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
if (first_in_pin == NULL) {
mp_raise_ValueError_varg(translate("Missing first_in_pin. Instruction %d waits based on pin"), i);
}
if (wait_index > in_pin_count) {
if (wait_index >= in_pin_count) {
mp_raise_ValueError_varg(translate("Instruction %d waits on input outside of count"), i);
}
}

View File

@ -190,8 +190,8 @@ STATIC mp_obj_t mp_builtin_dir(size_t n_args, const mp_obj_t *args) {
// Implemented by probing all possible qstrs with mp_load_method_maybe
size_t nqstr = QSTR_TOTAL();
for (size_t i = MP_QSTR_ + 1; i < nqstr; ++i) {
mp_obj_t dest[2];
mp_load_method_protected(args[0], i, dest, false);
mp_obj_t dest[2] = {};
mp_load_method_protected(args[0], i, dest, true);
if (dest[0] != MP_OBJ_NULL) {
#if MICROPY_PY_ALL_SPECIAL_METHODS
// Support for __dir__: see if we can dispatch to this special method

View File

@ -106,6 +106,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mdns_remoteservice_get_port_obj, remoteservice_
MP_PROPERTY_GETTER(mdns_remoteservice_port_obj,
(mp_obj_t)&mdns_remoteservice_get_port_obj);
//| ipv4_address: Optional[ipaddress.IPv4Address]
//| """IP v4 Address of the remote service. None if no A records are found."""
//|
STATIC mp_obj_t _mdns_remoteservice_get_ipv4_address(mp_obj_t self) {
return common_hal_mdns_remoteservice_get_ipv4_address(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(mdns_remoteservice_get_ipv4_address_obj, _mdns_remoteservice_get_ipv4_address);
MP_PROPERTY_GETTER(mdns_remoteservice_ipv4_address_obj,
(mp_obj_t)&mdns_remoteservice_get_ipv4_address_obj);
//| def __del__(self) -> None:
//| """Deletes the RemoteService object."""
//| ...
@ -123,6 +135,7 @@ STATIC const mp_rom_map_elem_t mdns_remoteservice_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_service_type), MP_ROM_PTR(&mdns_remoteservice_service_type_obj) },
{ MP_ROM_QSTR(MP_QSTR_protocol), MP_ROM_PTR(&mdns_remoteservice_protocol_obj) },
{ MP_ROM_QSTR(MP_QSTR_port), MP_ROM_PTR(&mdns_remoteservice_port_obj) },
{ MP_ROM_QSTR(MP_QSTR_ipv4_address), MP_ROM_PTR(&mdns_remoteservice_ipv4_address_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mdns_remoteservice_deinit_obj) },
};

View File

@ -38,4 +38,8 @@ const char *common_hal_mdns_remoteservice_get_protocol(mdns_remoteservice_obj_t
const char *common_hal_mdns_remoteservice_get_instance_name(mdns_remoteservice_obj_t *self);
const char *common_hal_mdns_remoteservice_get_hostname(mdns_remoteservice_obj_t *self);
mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self);
mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self);
void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self);
// For internal use.
uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self);

View File

@ -136,7 +136,7 @@ MP_PROPERTY_GETSET(mdns_server_instance_name_obj,
//| :param float/int timeout: Time to wait for responses"""
//| ...
//|
STATIC mp_obj_t mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
STATIC mp_obj_t _mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mdns_server_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
check_for_deinit(self);
@ -156,7 +156,7 @@ STATIC mp_obj_t mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
return common_hal_mdns_server_find(self, service_type, protocol, timeout);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, mdns_server_find);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, _mdns_server_find);
//| def advertise_service(self, *, service_type: str, protocol: str, port: int) -> None:
//| """Respond to queries for the given service with the given port.

View File

@ -30,6 +30,8 @@
#include "common-hal/mdns/Server.h"
#include "shared-bindings/mdns/RemoteService.h"
extern const mp_obj_type_t mdns_server_type;
void common_hal_mdns_server_construct(mdns_server_obj_t *self, mp_obj_t network_interface);
@ -41,3 +43,8 @@ const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self);
void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const char *instance_name);
mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_float_t timeout);
void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port);
// For internal use.
void mdns_server_construct(mdns_server_obj_t *self, bool workflow);
size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol,
mp_float_t timeout, mdns_remoteservice_obj_t *out, size_t out_len);

View File

@ -75,7 +75,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4,
//| creating a new socket of type SOCK_STREAM.
//| Returns a tuple of (new_socket, remote_address)"""
//|
STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) {
STATIC mp_obj_t _socketpool_socket_accept(mp_obj_t self_in) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t ip[4];
uint32_t port;
@ -87,7 +87,7 @@ STATIC mp_obj_t socketpool_socket_accept(mp_obj_t self_in) {
tuple_contents[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
return mp_obj_new_tuple(2, tuple_contents);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, socketpool_socket_accept);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, _socketpool_socket_accept);
//| def bind(self, address: Tuple[str, int]) -> None:
//| """Bind a socket to an address
@ -120,12 +120,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_b
//| def close(self) -> None:
//| """Closes this Socket and makes its resources available to its SocketPool."""
//|
STATIC mp_obj_t socketpool_socket_close(mp_obj_t self_in) {
STATIC mp_obj_t _socketpool_socket_close(mp_obj_t self_in) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_socketpool_socket_close(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, socketpool_socket_close);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, _socketpool_socket_close);
//| def connect(self, address: Tuple[str, int]) -> None:
//| """Connect a socket to a remote address
@ -155,7 +155,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke
//| def listen(self, backlog: int) -> None:
//| """Set socket to listen for incoming connections
//|
//| :param ~int backlog: length of backlog queue for waiting connetions"""
//| :param ~int backlog: length of backlog queue for waiting connections"""
//| ...
//|
STATIC mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) {
@ -208,7 +208,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool
//| :param int bufsize: optionally, a maximum number of bytes to read."""
//| ...
//|
STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t _socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
if (common_hal_socketpool_socket_get_closed(self)) {
// Bad file number.
@ -238,7 +238,7 @@ STATIC mp_obj_t socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args)
mp_int_t ret = common_hal_socketpool_socket_recv_into(self, (byte *)bufinfo.buf, len);
return mp_obj_new_int_from_uint(ret);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, socketpool_socket_recv_into);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3, _socketpool_socket_recv_into);
//| def send(self, bytes: ReadableBuffer) -> int:
//| """Send some bytes to the connected remote address.
@ -247,7 +247,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3
//| :param ~bytes bytes: some bytes to send"""
//| ...
//|
STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
STATIC mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (common_hal_socketpool_socket_get_closed(self)) {
// Bad file number.
@ -264,7 +264,7 @@ STATIC mp_obj_t socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
return mp_obj_new_int_from_uint(ret);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, socketpool_socket_send);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_send);
//| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int:
//| """Send some bytes to a specific address.

View File

@ -47,4 +47,11 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self,
const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len);
void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms);
// Non-allocating versions for internal use.
int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port);
void socketpool_socket_close(socketpool_socket_obj_t *self);
int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len);
int socketpool_socket_recv_into(socketpool_socket_obj_t *self,
const uint8_t *buf, uint32_t len);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKET_H

View File

@ -52,4 +52,10 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self,
const char *host);
// Non-allocating version for internal use. These sockets are not registered and, therefore, not
// closed automatically.
bool socketpool_socket(socketpool_socketpool_obj_t *self,
socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type,
socketpool_socket_obj_t *sock);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SOCKETPOOL_SOCKETPOOL_H

View File

@ -138,6 +138,27 @@ MP_PROPERTY_GETSET(wifi_radio_mac_address_obj,
(mp_obj_t)&wifi_radio_get_mac_address_obj,
(mp_obj_t)&wifi_radio_set_mac_address_obj);
//| tx_power: int
//| """Wifi transmission power, in dBm."""
//|
STATIC mp_obj_t wifi_radio_get_tx_power(mp_obj_t self_in) {
wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_int(common_hal_wifi_radio_get_tx_power(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_tx_power_obj, wifi_radio_get_tx_power);
STATIC mp_obj_t wifi_radio_set_tx_power(mp_obj_t self_in, mp_obj_t tx_power_in) {
mp_int_t tx_power = mp_obj_get_int(tx_power_in);
wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in);
common_hal_wifi_radio_set_tx_power(self, tx_power);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_tx_power_obj, wifi_radio_set_tx_power);
MP_PROPERTY_GETSET(wifi_radio_tx_power_obj,
(mp_obj_t)&wifi_radio_get_tx_power_obj,
(mp_obj_t)&wifi_radio_set_tx_power_obj);
//| mac_address_ap: ReadableBuffer
//| """MAC address for the AP. When the address is altered after interface is started
//| the changes would only be reflected once the interface restarts."""
@ -549,6 +570,7 @@ STATIC const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mac_address), MP_ROM_PTR(&wifi_radio_mac_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_mac_address_ap), MP_ROM_PTR(&wifi_radio_mac_address_ap_obj) },
{ MP_ROM_QSTR(MP_QSTR_tx_power), MP_ROM_PTR(&wifi_radio_tx_power_obj) },
{ MP_ROM_QSTR(MP_QSTR_start_scanning_networks), MP_ROM_PTR(&wifi_radio_start_scanning_networks_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop_scanning_networks), MP_ROM_PTR(&wifi_radio_stop_scanning_networks_obj) },

View File

@ -82,6 +82,9 @@ extern void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const
extern mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self);
extern void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint8_t *mac);
extern uint8_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self);
extern void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const uint8_t power);
extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self);
extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self);

View File

@ -43,7 +43,8 @@ enum {
enum {
AUTORELOAD_SUSPEND_REPL = 0x1,
AUTORELOAD_SUSPEND_BLE = 0x2,
AUTORELOAD_SUSPEND_USB = 0x4
AUTORELOAD_SUSPEND_USB = 0x4,
AUTORELOAD_SUSPEND_WEB = 0x8
};
typedef struct {

View File

@ -178,7 +178,7 @@ void print_safe_mode_message(safe_mode_t reason) {
message = translate("Boot device must be first device (interface #0).");
break;
case WATCHDOG_RESET:
message = translate("Watchdog timer expired.");
message = translate("Internal watchdog timer expired.");
break;
case NO_CIRCUITPY:
message = translate("CIRCUITPY drive could not be found or created.");

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8">
<script src="/directory.js" defer=true></script>
</head>
<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></tr></template>
<table>
<thead><tr><th>Type</th><th>Size</th><th>Path</th><th>Modified</th><th></th></tr></thead>
<tbody></tbody>
</table>
<hr>
<input type="file" id="files" multiple><button type="submit" id="upload">Upload</button>
<hr>
+🗀&nbsp;<input type="text" id="name"><button type="submit" id="mkdir">Create Directory</button>
</body></html>

View File

@ -0,0 +1,194 @@
let new_directory_name = document.getElementById("name");
let files = document.getElementById("files");
var url_base = window.location;
var current_path;
var editable = undefined;
async function refresh_list() {
current_path = window.location.hash.substr(1);
if (current_path == "") {
current_path = "/";
}
// Do the fetch first because the browser will prompt for credentials.
const response = await fetch(new URL("/fs" + current_path, url_base),
{
headers: {
"Accept": "application/json"
},
credentials: "include"
}
);
const data = await response.json();
var new_children = [];
var title = document.querySelector("title");
title.textContent = current_path;
var path = document.querySelector("#path");
path.textContent = current_path;
var template = document.querySelector('#row');
if (editable === undefined) {
const status = await fetch(new URL("/fs/", url_base),
{
method: "OPTIONS",
credentials: "include"
}
);
editable = status.headers.get("Access-Control-Allow-Methods").includes("DELETE");
new_directory_name.disabled = !editable;
files.disabled = !editable;
if (!editable) {
let usbwarning = document.querySelector("#usbwarning");
usbwarning.style.display = "block";
}
}
if (window.location.path != "/fs/") {
var clone = template.content.cloneNode(true);
var td = clone.querySelectorAll("td");
td[0].textContent = "🗀";
var path = clone.querySelector("a");
let parent = new URL("..", "file://" + current_path);
path.href = "#" + parent.pathname;
path.textContent = "..";
// Remove the delete button
td[4].replaceChildren();
new_children.push(clone);
}
for (const f of data) {
// Clone the new row and insert it into the table
var clone = template.content.cloneNode(true);
var td = clone.querySelectorAll("td");
var icon = "⬇";
var file_path = current_path + f.name;
let api_url = new URL("/fs" + file_path, url_base);
if (f.directory) {
file_path = "#" + file_path + "/";
api_url += "/";
} else {
file_path = api_url;
}
if (f.directory) {
icon = "🗀";
} else if(f.name.endsWith(".txt") ||
f.name.endsWith(".py") ||
f.name.endsWith(".js") ||
f.name.endsWith(".json")) {
icon = "🖹";
} else if (f.name.endsWith(".html")) {
icon = "🌐";
}
td[0].textContent = icon;
td[1].textContent = f.file_size;
var path = clone.querySelector("a");
path.href = file_path;
path.textContent = f.name;
td[3].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;
new_children.push(clone);
}
var tbody = document.querySelector("tbody");
tbody.replaceChildren(...new_children);
}
async function find_devices() {
const version_response = await fetch("/cp/version.json");
if (version_response.ok) {
url_base = new URL("/", window.location).href;
} else {
// TODO: Remove this when we've settled things. It is only used when this file isn't hosted
// by a CP device.
const response = await fetch("http://circuitpython.local/cp/devices.json");
let url = new URL("/", response.url);
url_base = url.href;
const data = await response.json();
}
refresh_list();
}
async function mkdir(e) {
const response = await fetch(
new URL("/fs" + current_path + new_directory_name.value + "/", url_base),
{
method: "PUT",
headers: {
'X-Timestamp': Date.now()
}
}
);
if (response.ok) {
refresh_list();
new_directory_name.value = "";
mkdir_button.disabled = true;
}
}
async function upload(e) {
for (const file of files.files) {
let file_path = new URL("/fs" + current_path + file.name, url_base);
const response = await fetch(file_path,
{
method: "PUT",
headers: {
'Content-Type': 'application/octet-stream',
'X-Timestamp': file.lastModified
},
body: file
}
)
if (response.ok) {
refresh_list();
files.value = "";
upload_button.disabled = true;
}
}
}
async function del(e) {
let fn = new URL(e.target.value);
var prompt = "Delete " + fn.pathname.substr(3);
if (e.target.value.endsWith("/")) {
prompt += " and all of its contents?";
} else {
prompt += "?";
}
if (confirm(prompt)) {
const response = await fetch(e.target.value,
{
method: "DELETE"
}
)
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;
}
mkdir_button.disabled = new_directory_name.value.length == 0;
new_directory_name.oninput = () => {
mkdir_button.disabled = new_directory_name.value.length == 0;
}
window.onhashchange = refresh_list;

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<title>CircuitPython</title>
<meta charset="UTF-8">
</head>
<script src="/welcome.js" defer=true></script>
<body>
<h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;Welcome!</h1>
Welcome to CircuitPython's Web API. Go to the <a href="/fs/">file browser</a> to work with files in the CIRCUITPY drive. Make sure you've set <code>CIRCUITPY_WEB_API_PASSWORD='somepassword'</code> in <code>/.env</code>. Provide the password when the browser prompts for it. Leave the username blank.
<h2>Device Info</h2>
Board: <a id="board"></a><br>
Version: <span id="version"></span><br>
Hostname: <a id="hostname"></a><br>
IP: <a id="ip"></a>
<h2>Other Devices</h2>
Here are other CircuitPython devices on your network:
<ul id="devices">
</ul>
</body>
</html>

View File

@ -0,0 +1,62 @@
var url_base = window.location;
var current_path;
var mdns_works = window.location.hostname.endsWith(".local");
async function find_devices() {
var version_response = await fetch("/cp/version.json");
if (version_response.ok) {
url_base = new URL("/", window.location).href;
} else {
// TODO: Remove this when we've settled things. It is only used when this file isn't hosted
// by a CP device.
version_response = await fetch("http://circuitpython.local/cp/version.json", {mode: "cors"});
mdns_works = mdns_works || version_response.redirected;
if (!version_response.ok && version_response.redirected) {
version_response = await fetch(version_response.url);
}
let url = new URL("/", version_response.url);
url_base = url.href;
}
const version_info = await version_response.json();
let version_span = document.querySelector("#version");
version_span.textContent = version_info.version;
let board_link = document.querySelector("#board");
board_link.href = "https://circuitpython.org/board/" + version_info.board_id + "/";
board_link.textContent = version_info.board_name;
let hostname = document.querySelector("#hostname");
var port = "";
if (version_info.port != 80) {
port = ":" + version_info.port;
}
hostname.href = "http://" + version_info.hostname + ".local" + port + "/";
hostname.textContent = version_info.hostname;
let ip = document.querySelector("#ip");
ip.href = "http://" + version_info.ip + port + "/";
ip.textContent = version_info.ip;
const response = await fetch(new URL("/cp/devices.json", url_base));
const data = await response.json();
let device_list = document.querySelector("#devices");
let new_devices = [];
for (device of data.devices) {
let li = document.createElement("li");
let a = document.createElement("a");
li.appendChild(a);
var port = "";
if (device.port != 80) {
port = ":" + version_info.port;
}
var server;
if (mdns_works) {
server = device.hostname + ".local";
} else {
server = device.ip;
}
a.href = "http://" + server + port + "/";
a.textContent = device.instance_name + " (" + device.hostname + ")";
new_devices.push(li);
}
device_list.replaceChildren(...new_devices);
}
find_devices();

File diff suppressed because it is too large Load Diff

View File

@ -28,8 +28,9 @@
#include <stdbool.h>
void supervisor_wifi_background(void);
void supervisor_wifi_init(void);
// This background function should be called repeatedly. It cannot be done based
// on events.
void supervisor_web_workflow_background(void);
void supervisor_web_workflow_status(void);
void supervisor_start_web_workflow(void);
void supervisor_stop_web_workflow(void);

View File

@ -20,6 +20,30 @@ SRC_SUPERVISOR = \
NO_USB ?= $(wildcard supervisor/usb.c)
ifeq ($(CIRCUITPY_USB),1)
CIRCUITPY_CREATOR_ID ?= $(USB_VID)
CIRCUITPY_CREATION_ID ?= $(USB_PID)
endif
ifneq ($(CIRCUITPY_CREATOR_ID),)
CFLAGS += -DCIRCUITPY_CREATOR_ID=$(CIRCUITPY_CREATOR_ID)
endif
ifneq ($(CIRCUITPY_CREATION_ID),)
CFLAGS += -DCIRCUITPY_CREATION_ID=$(CIRCUITPY_CREATION_ID)
endif
ifeq ($(CIRCUITPY_BLEIO),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/bluetooth.c
ifeq ($(CIRCUITPY_BLE_FILE_SERVICE),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/file_transfer.c
endif
ifeq ($(CIRCUITPY_SERIAL_BLE),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/serial.c
endif
endif
INTERNAL_FLASH_FILESYSTEM ?= 0
CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
@ -38,20 +62,6 @@ else
SRC_SUPERVISOR += supervisor/shared/filesystem.c
endif
ifeq ($(CIRCUITPY_BLEIO),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/bluetooth.c
CIRCUITPY_CREATOR_ID ?= $(USB_VID)
CIRCUITPY_CREATION_ID ?= $(USB_PID)
CFLAGS += -DCIRCUITPY_CREATOR_ID=$(CIRCUITPY_CREATOR_ID)
CFLAGS += -DCIRCUITPY_CREATION_ID=$(CIRCUITPY_CREATION_ID)
ifeq ($(CIRCUITPY_BLE_FILE_SERVICE),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/file_transfer.c
endif
ifeq ($(CIRCUITPY_SERIAL_BLE),1)
SRC_SUPERVISOR += supervisor/shared/bluetooth/serial.c
endif
endif
# Choose which flash filesystem impl to use.
# (Right now INTERNAL_FLASH_FILESYSTEM and (Q)SPI_FLASH_FILESYSTEM are mutually exclusive.
# But that might not be true in the future.)
@ -149,8 +159,18 @@ ifeq ($(CIRCUITPY_USB),1)
endif
endif
STATIC_RESOURCES = $(wildcard $(TOP)/supervisor/shared/web_workflow/static/*)
$(BUILD)/autogen_web_workflow_static.c: ../../tools/gen_web_workflow_static.py $(STATIC_RESOURCES) | $(HEADER_BUILD)
$(STEPECHO) "GEN $@"
$(Q)$(PYTHON) $< \
--output_c_file $@ \
$(STATIC_RESOURCES)
ifeq ($(CIRCUITPY_WEB_WORKFLOW),1)
SRC_SUPERVISOR += supervisor/shared/web_workflow/web_workflow.c
SRC_SUPERVISOR += $(BUILD)/autogen_web_workflow_static.c
endif
SRC_TINYUSB = $(filter lib/tinyusb/%.c, $(SRC_SUPERVISOR))
@ -207,4 +227,4 @@ $(BUILD)/autogen_display_resources-$(TRANSLATION).c: ../../tools/gen_display_res
$(Q)$(PYTHON) ../../tools/gen_display_resources.py \
--font $(CIRCUITPY_DISPLAY_FONT) \
--sample_file $(TOP)/locale/$(TRANSLATION).po \
--output_c_file $(BUILD)/autogen_display_resources-$(TRANSLATION).c
--output_c_file $@

View File

@ -77,6 +77,7 @@ extension_by_board = {
"ai_thinker_esp32-c3s-2m": BIN,
"espressif_esp32c3_devkitm_1_n4": BIN,
"lilygo_ttgo_t-01c3": BIN,
"lolin_c3_mini": BIN,
"microdev_micro_c3": BIN,
"lilygo_ttgo_t-oi-plus": BIN,
# broadcom

View File

@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
#
# SPDX-License-Identifier: MIT
import argparse
import gzip
import mimetypes
import pathlib
parser = argparse.ArgumentParser(description="Generate displayio resources.")
parser.add_argument("--output_c_file", type=argparse.FileType("w"), required=True)
parser.add_argument("files", metavar="FILE", type=argparse.FileType("rb"), nargs="+")
args = parser.parse_args()
c_file = args.output_c_file
c_file.write(f"// Autogenerated by tools/gen_web_workflow_static.py\n")
c_file.write(f"#include <stdint.h>\n\n")
for f in args.files:
path = pathlib.Path(f.name)
variable = path.name.replace(".", "_")
uncompressed = f.read()
ulen = len(uncompressed)
compressed = gzip.compress(uncompressed)
clen = len(compressed)
compressed = ", ".join([hex(x) for x in compressed])
mime = mimetypes.guess_type(f.name)[0]
c_file.write(f"// {f.name}\n")
c_file.write(f"// Original length: {ulen} Compressed length: {clen}\n")
c_file.write(f"const uint32_t {variable}_length = {clen};\n")
c_file.write(f'const char* {variable}_content_type = "{mime}";\n')
c_file.write(f"const uint8_t {variable}[{clen}] = {{{compressed}}};\n\n")