Merge remote-tracking branch 'origin/main' into extra-memset
This commit is contained in:
commit
162fa6ef02
|
@ -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
|
||||
|
@ -382,7 +383,8 @@ jobs:
|
|||
if: ${{ needs.test.outputs.boards-espressif != '[]' }}
|
||||
steps:
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
id: py3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
|
@ -400,7 +402,7 @@ jobs:
|
|||
id: idf-cache
|
||||
with:
|
||||
path: ${{ github.workspace }}/.idf_tools
|
||||
key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/espressif/esp-idf/HEAD') }}-20220404
|
||||
key: ${{ runner.os }}-idf-tools-${{ hashFiles('.git/modules/ports/espressif/esp-idf/HEAD') }}-${{ steps.py3.outputs.python-path }}-20220404
|
||||
- name: Clone IDF submodules
|
||||
run: |
|
||||
(cd $IDF_PATH && git submodule update --init)
|
||||
|
@ -486,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
|
||||
|
|
|
@ -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
|
||||
|
@ -289,3 +289,21 @@
|
|||
[submodule "frozen/pew-pewpew-lcd"]
|
||||
path = frozen/pew-pewpew-lcd
|
||||
url = https://github.com/pypewpew/pew-pewpew-lcd.git
|
||||
[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
|
||||
|
|
|
@ -9,16 +9,15 @@
|
|||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3"
|
||||
|
||||
submodules:
|
||||
include:
|
||||
- extmod/ulab
|
||||
os: ubuntu-20.04
|
||||
tools:
|
||||
python: "3"
|
||||
jobs:
|
||||
post_install:
|
||||
- python tools/ci_fetch_deps.py docs HEAD
|
||||
|
||||
formats:
|
||||
- pdf
|
||||
- pdf
|
||||
|
||||
python:
|
||||
install:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
15
README.rst
15
README.rst
|
@ -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
|
||||
|
@ -120,7 +122,7 @@ Behavior
|
|||
make each file independent from each other.
|
||||
|
||||
- ``boot.py`` runs only once on start up before
|
||||
USB is initialized. This lays the ground work for configuring USB at
|
||||
workflows are initialized. This lays the ground work for configuring USB at
|
||||
startup rather than it being fixed. Since serial is not available,
|
||||
output is written to ``boot_out.txt``.
|
||||
- ``code.py`` (or ``main.py``) is run after every reload until it
|
||||
|
@ -135,7 +137,10 @@ Behavior
|
|||
possible to fix code that causes nasty crashes by making it available through mass storage after
|
||||
the crash. A reset (the button) is needed after it's fixed to get back into normal mode.
|
||||
- RGB status LED indicating CircuitPython state.
|
||||
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
|
||||
- One green flash - code completed without error.
|
||||
- Two red flashes - code ended due to an exception.
|
||||
- Three yellow flashes - safe mode. May be due to CircuitPython internal error.
|
||||
- Re-runs ``code.py`` or other main file after file system writes by a workflow. (Disable with
|
||||
``supervisor.disable_autoreload()``)
|
||||
- Autoreload is disabled while the REPL is active.
|
||||
- Main is one of these: ``code.txt``, ``code.py``, ``main.py``,
|
||||
|
|
19
conf.py
19
conf.py
|
@ -33,6 +33,25 @@ from sphinx import addnodes
|
|||
|
||||
tools_describe = str(pathlib.Path(__file__).parent / "tools/describe")
|
||||
|
||||
# Monkeypatch autoapi
|
||||
def _format_args(args_info, include_annotations=True, ignore_self=None):
|
||||
result = []
|
||||
|
||||
for i, (prefix, name, annotation, default) in enumerate(args_info):
|
||||
if i == 0 and ignore_self is not None and name == ignore_self:
|
||||
continue
|
||||
formatted = "{}{}{}{}".format(
|
||||
prefix or "",
|
||||
name or "",
|
||||
": {}".format(annotation) if annotation and include_annotations else "",
|
||||
(" = {}" if annotation else "={}").format(default) if default else "",
|
||||
)
|
||||
result.append(formatted)
|
||||
return ", ".join(result)
|
||||
|
||||
import autoapi.mappers.python.objects as objects
|
||||
objects._format_args = _format_args
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 266ea20ed80104c315dcb124b482fa5f9f48cdec
|
||||
Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd
|
|
@ -49,6 +49,10 @@
|
|||
#include "shared-bindings/_bleio/ScanEntry.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
|
||||
#if CIRCUITPY_DOTENV
|
||||
#include "shared-module/dotenv/__init__.h"
|
||||
#endif
|
||||
|
||||
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
|
||||
#define SEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000000) / (RESOLUTION))
|
||||
#define UNITS_TO_SEC(TIME, RESOLUTION) (((TIME)*(RESOLUTION)) / 1000000)
|
||||
|
@ -278,17 +282,27 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0
|
|||
// Get various values and limits set by the adapter.
|
||||
// Set event mask.
|
||||
STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
|
||||
mp_int_t name_len = 0;
|
||||
|
||||
const size_t len = sizeof(default_ble_name);
|
||||
#if CIRCUITPY_DOTENV
|
||||
char ble_name[32];
|
||||
name_len = dotenv_get_key("/.env", "CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name) - 1);
|
||||
if (name_len > 0) {
|
||||
self->name = mp_obj_new_str(ble_name, (size_t)name_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
bt_addr_t addr;
|
||||
hci_check_error(hci_read_bd_addr(&addr));
|
||||
if (name_len <= 0) {
|
||||
name_len = sizeof(default_ble_name);
|
||||
bt_addr_t addr;
|
||||
hci_check_error(hci_read_bd_addr(&addr));
|
||||
|
||||
default_ble_name[len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf];
|
||||
default_ble_name[len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf];
|
||||
default_ble_name[len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf];
|
||||
default_ble_name[len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf];
|
||||
self->name = mp_obj_new_str(default_ble_name, len);
|
||||
default_ble_name[name_len - 4] = nibble_to_hex_lower[addr.val[1] >> 4 & 0xf];
|
||||
default_ble_name[name_len - 3] = nibble_to_hex_lower[addr.val[1] & 0xf];
|
||||
default_ble_name[name_len - 2] = nibble_to_hex_lower[addr.val[0] >> 4 & 0xf];
|
||||
default_ble_name[name_len - 1] = nibble_to_hex_lower[addr.val[0] & 0xf];
|
||||
self->name = mp_obj_new_str(default_ble_name, (uint8_t)name_len);
|
||||
}
|
||||
|
||||
// Get version information.
|
||||
if (hci_read_local_version(&self->hci_version, &self->hci_revision, &self->lmp_version,
|
||||
|
|
|
@ -57,9 +57,9 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
|
|||
self->value = mp_obj_new_bytes(initial_value_bufinfo->buf, initial_value_bufinfo->len);
|
||||
|
||||
const mp_int_t max_length_max = 512;
|
||||
if (max_length < 0 || max_length > max_length_max) {
|
||||
mp_raise_ValueError(translate("max_length must be <= 512"));
|
||||
}
|
||||
|
||||
mp_arg_validate_int_range(max_length, 0, max_length_max, MP_QSTR_max_length);
|
||||
|
||||
self->max_length = max_length;
|
||||
self->fixed_length = fixed_length;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "shared-bindings/_bleio/Service.h"
|
||||
#include "shared-bindings/_bleio/UUID.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
STATIC uint16_t max_mtu = BT_ATT_DEFAULT_LE_MTU; // 23
|
||||
STATIC unsigned long timeout = 5000;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
Environment Variables
|
||||
=====================
|
||||
|
||||
CircuitPython 8.0.0 introduces support for environment variables. Environment
|
||||
variables are commonly used to store "secrets" such as Wi-Fi passwords and API
|
||||
keys. This method *does not* make them secure. It only separates them from the
|
||||
code.
|
||||
|
||||
CircuitPython supports these by mimicking the `dotenv <https://github.com/theskumar/python-dotenv>`_
|
||||
CPython library. Other languages such as Javascript, PHP and Ruby also have
|
||||
dotenv libraries.
|
||||
|
||||
These libraries store environment variables in a ``.env`` file. Here is a simple
|
||||
example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
KEY1='value1'
|
||||
# Comment
|
||||
KEY2='value2
|
||||
is multiple lines'
|
||||
|
||||
CircuitPython uses the ``.env`` at the drive root (no folder) as the environment.
|
||||
User code can access the values from the file using `os.getenv()`. It is
|
||||
recommended to save any values used repeatedly in a variable because `os.getenv()`
|
||||
will parse the ``/.env`` on every access.
|
||||
|
||||
CircuitPython behavior
|
||||
----------------------
|
||||
|
||||
CircuitPython will also read the environment to configure its behavior. Other
|
||||
keys are ignored by CircuitPython. Here are the keys it uses:
|
||||
|
||||
CIRCUITPY_BLE_NAME
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Default BLE name the board advertises as, including for the BLE workflow.
|
||||
|
||||
CIRCUITPY_WEB_API_PASSWORD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Password required to make modifications to the board from the Web Workflow.
|
||||
|
||||
CIRCUITPY_WIFI_PASSWORD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID.
|
||||
|
||||
CIRCUITPY_WIFI_SSID
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Wi-Fi SSID to auto-connect to even if user code is not running.
|
|
@ -22,6 +22,8 @@ Full Table of Contents
|
|||
supported_ports.rst
|
||||
troubleshooting.rst
|
||||
drivers.rst
|
||||
workflows
|
||||
environment.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
.. module:: hashlib
|
||||
:synopsis: hashing algorithms
|
||||
:noindex:
|
||||
|
||||
|see_cpython_module| :mod:`cpython:hashlib`.
|
||||
|
||||
|
|
|
@ -79,8 +79,6 @@ as a natural "TODO" list. An example minimal build list is shown below:
|
|||
# any port once their prerequisites in common-hal are complete.
|
||||
# Requires DigitalIO:
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
# Requires DigitalIO
|
||||
CIRCUITPY_GAMEPADSHIFT = 0
|
||||
# Requires neopixel_write or SPI (dotstar)
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
# Requires OS
|
||||
|
|
|
@ -45,12 +45,10 @@ shared-bindings/audiomp3/__init__.rst shared-bindings/audiomp3/
|
|||
shared-bindings/audiopwmio/PWMAudioOut.rst shared-bindings/audiopwmio/#audiopwmio.PWMAudioOut
|
||||
shared-bindings/audiopwmio/__init__.rst shared-bindings/audiopwmio/
|
||||
shared-bindings/bitbangio/I2C.rst shared-bindings/bitbangio/#bitbangio.I2C
|
||||
shared-bindings/bitbangio/OneWire.rst shared-bindings/bitbangio/#bitbangio.OneWire
|
||||
shared-bindings/bitbangio/SPI.rst shared-bindings/bitbangio/#bitbangio.SPI
|
||||
shared-bindings/bitbangio/__init__.rst shared-bindings/bitbangio/
|
||||
shared-bindings/board/__init__.rst shared-bindings/board/
|
||||
shared-bindings/busio/I2C.rst shared-bindings/busio/#busio.I2C
|
||||
shared-bindings/busio/OneWire.rst shared-bindings/busio/#busio.OneWire
|
||||
shared-bindings/busio/Parity.rst shared-bindings/busio/#busio.Parity
|
||||
shared-bindings/busio/SPI.rst shared-bindings/busio/#busio.SPI
|
||||
shared-bindings/busio/UART.rst shared-bindings/busio/#busio.UART
|
||||
|
@ -82,10 +80,6 @@ shared-bindings/framebufferio/FramebufferDisplay.rst shared-bindings/framebuffer
|
|||
shared-bindings/framebufferio/__init__.rst shared-bindings/framebufferio/
|
||||
shared-bindings/frequencyio/FrequencyIn.rst shared-bindings/frequencyio/#frequencyio.FrequencyIn
|
||||
shared-bindings/frequencyio/__init__.rst shared-bindings/frequencyio/
|
||||
shared-bindings/gamepad/GamePad.rst shared-bindings/gamepad/#gamepad.GamePad
|
||||
shared-bindings/gamepad/__init__.rst shared-bindings/gamepad/
|
||||
shared-bindings/gamepadshift/GamePadShift.rst shared-bindings/gamepadshift/#gamepadshift.GamePadShift
|
||||
shared-bindings/gamepadshift/__init__.rst shared-bindings/gamepadshift/
|
||||
shared-bindings/gnss/__init__.rst shared-bindings/gnss/
|
||||
shared-bindings/i2cperipheral/__init__.rst shared-bindings/i2cperipheral/
|
||||
shared-bindings/i2csecondary/__init__.rst shared-bindings/i2csecondary/
|
||||
|
@ -101,6 +95,7 @@ shared-bindings/neopixel_write/__init__.rst shared-bindings/neopixel_write/
|
|||
shared-bindings/network/__init__.rst shared-bindings/network/
|
||||
shared-bindings/nvm/ByteArray.rst shared-bindings/nvm/#nvm.ByteArray
|
||||
shared-bindings/nvm/__init__.rst shared-bindings/nvm/
|
||||
shared-bindings/onewireio/OneWire.rst shared-bindings/onewireio/#onewireio.OneWire
|
||||
shared-bindings/os/__init__.rst shared-bindings/os/
|
||||
shared-bindings/protomatter/__init__.rst shared-bindings/protomatter/
|
||||
shared-bindings/ps2io/Ps2.rst shared-bindings/ps2io/#ps2io.Ps2
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
# 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.
|
||||
|
||||
To change the default BLE advertising name without (or before) running user code, the desired name
|
||||
can be put in the `/.env` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately
|
||||
30 characters depending on the port's settings and will be truncated if longer.
|
||||
|
||||
### 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/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"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `/cp/serial/`
|
||||
|
||||
|
||||
Serves a basic serial terminal program when a `GET` request is received without the
|
||||
`Upgrade: websocket` header. Otherwise the socket is upgraded to a WebSocket. See WebSockets below for more detail.
|
||||
|
||||
This is an authenticated endpoint in both modes.
|
||||
|
||||
#### `/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"
|
||||
}
|
||||
```
|
||||
|
||||
### Static files
|
||||
|
||||
* `/favicon.ico` - Blinka
|
||||
* `/directory.js` - JavaScript for `/fs/`
|
||||
* `/welcome.js` - JavaScript for `/`
|
||||
|
||||
### WebSocket
|
||||
|
||||
The CircuitPython serial interactions are available over a WebSocket. A WebSocket begins as a
|
||||
special HTTP request that gets upgraded to a WebSocket. Authentication happens before upgrading.
|
||||
|
||||
WebSockets are *not* bare sockets once upgraded. Instead they have their own framing format for data.
|
||||
CircuitPython can handle PING and CLOSE opcodes. All others are treated as TEXT. Data to
|
||||
CircuitPython is expected to be masked UTF-8, as the spec requires. Data from CircuitPython to the
|
||||
client is unmasked. It is also unbuffered so the client will get a variety of frame sizes.
|
||||
|
||||
Only one WebSocket at a time is supported.
|
|
@ -33,6 +33,8 @@
|
|||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#endif
|
||||
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UASYNCIO
|
||||
|
||||
// Used when task cannot be guaranteed to be non-NULL.
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
static void check_not_unicode(const mp_obj_t arg) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (mp_obj_is_str(arg)) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "py/objtuple.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UCTYPES
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UHASHLIB
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UHEAPQ
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UJSON
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UTIMEQ
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UZLIB
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5d01882c41dbc4115bc94f0b61c093d5a6b812b6
|
||||
Subproject commit 346c936e14c6ea3a8d3d65cb1fa46202dc92999d
|
|
@ -20,7 +20,7 @@
|
|||
#include "extmod/vfs_fat.h"
|
||||
#include "shared/timeutils/timeutils.h"
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if FF_MAX_SS == FF_MIN_SS
|
||||
#define SECSIZE(fs) (FF_MIN_SS)
|
||||
|
@ -30,6 +30,11 @@
|
|||
|
||||
#define mp_obj_fat_vfs_t fs_user_mount_t
|
||||
|
||||
// Factoring this common call saves about 90 bytes.
|
||||
STATIC NORETURN void mp_raise_OSError_fresult(FRESULT res) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
}
|
||||
|
||||
STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
|
||||
fs_user_mount_t *vfs = vfs_in;
|
||||
FILINFO fno;
|
||||
|
@ -64,7 +69,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
|||
// don't error out if no filesystem, to let mkfs()/mount() create one if wanted
|
||||
vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_NO_FILESYSTEM;
|
||||
} else if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(vfs);
|
||||
|
@ -97,7 +102,7 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
|
|||
res = f_mkfs(&vfs->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf));
|
||||
}
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
|
@ -172,7 +177,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
|
|||
iter->is_str = is_str_type;
|
||||
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(iter);
|
||||
|
@ -188,7 +193,7 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_in
|
|||
FRESULT res = f_stat(&self->fatfs, path, &fno);
|
||||
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
// check if path is a file or directory
|
||||
|
@ -196,7 +201,7 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_in
|
|||
res = f_unlink(&self->fatfs, path);
|
||||
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
return mp_const_none;
|
||||
} else {
|
||||
|
@ -226,7 +231,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
|
|||
FILINFO fno;
|
||||
FRESULT res = f_stat(&self->fatfs, old_path, &fno);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
if ((fno.fattrib & AM_DIR) != 0 &&
|
||||
strlen(new_path) > strlen(old_path) &&
|
||||
|
@ -245,7 +250,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
|
|||
if (res == FR_OK) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -259,7 +264,7 @@ STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
|
|||
if (res == FR_OK) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
|
||||
|
@ -273,7 +278,7 @@ STATIC mp_obj_t fat_vfs_chdir(mp_obj_t vfs_in, mp_obj_t path_in) {
|
|||
FRESULT res = f_chdir(&self->fatfs, path);
|
||||
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
|
@ -286,7 +291,7 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
|
|||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||
FRESULT res = f_getcwd(&self->fatfs, buf, sizeof(buf));
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
return mp_obj_new_str(buf, strlen(buf));
|
||||
}
|
||||
|
@ -307,7 +312,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
|
|||
} else {
|
||||
FRESULT res = f_stat(&self->fatfs, path, &fno);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +362,7 @@ STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
|
|||
FATFS *fatfs = &self->fatfs;
|
||||
FRESULT res = f_getfree(fatfs, &nclst);
|
||||
if (FR_OK != res) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
|
||||
|
@ -395,7 +400,7 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs
|
|||
res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||
}
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
self->blockdev.flags &= ~MP_BLOCKDEV_FLAG_NO_FILESYSTEM;
|
||||
|
||||
|
@ -416,7 +421,7 @@ STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) {
|
|||
char working_buf[12];
|
||||
FRESULT res = f_getlabel(&self->fatfs, working_buf, NULL);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
return mp_obj_new_str(working_buf, strlen(working_buf));
|
||||
}
|
||||
|
@ -431,7 +436,7 @@ STATIC mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) {
|
|||
if (res == FR_WRITE_PROTECTED) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Read-only filesystem"));
|
||||
}
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
|
|||
}
|
||||
|
||||
if (rwxa_count != 1 || plus_count > 1 || bt_count > 1 || bad_mode) {
|
||||
mp_raise_ValueError(translate("Invalid mode"));
|
||||
mp_arg_error_invalid(MP_QSTR_mode);
|
||||
}
|
||||
|
||||
assert(vfs != NULL);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "extmod/vfs_posix.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if (defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX) || (defined(MICROPY_VFS_POSIX_FILE) && MICROPY_VFS_POSIX_FILE)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9bd48820928afad549832fe9b4ae497b224007f0
|
||||
Subproject commit 13856be616eee2eb84280b7c4914951c1ddbfd36
|
|
@ -1 +1 @@
|
|||
Subproject commit 13c529288e9431541fe58cf7992d4f53f7ca3b76
|
||||
Subproject commit 7d9635ba1dda31ce45b84519c4da76ff86d0debe
|
|
@ -1 +1 @@
|
|||
Subproject commit 258bb62c58e545c38749b8a66f5872035b2384cb
|
||||
Subproject commit e5cf8206c0173228252ae74367cab85b0531488e
|
|
@ -1 +1 @@
|
|||
Subproject commit b96f0d279481446017ca1cc1ff4abf1f5a10346f
|
||||
Subproject commit 9addf6a26fef3a32c78d574c66452b6210eca5c5
|
|
@ -1 +1 @@
|
|||
Subproject commit f82d3ef195256aa71d274a34ea25f760d7e651d1
|
||||
Subproject commit 843def7daee741c8fb04fe21c3c7b98f22862471
|
|
@ -1 +1 @@
|
|||
Subproject commit 938f6bb335ba5e4c56a8062c591ff9f3c18c4297
|
||||
Subproject commit 0a045871d3da681d1c9c9578f09174bfc6d84f1d
|
|
@ -1 +1 @@
|
|||
Subproject commit 8e7e111a9ff39d3f4311caa7babeb451422c759f
|
||||
Subproject commit 6a429bcd0e6b22ee181197ce0477ae70f5adb80d
|
|
@ -1 +1 @@
|
|||
Subproject commit df2449815433e05ea0f89c19518ccde7a10a2faa
|
||||
Subproject commit 22931594bc52ab259eaf313d26219a507703c315
|
|
@ -1 +1 @@
|
|||
Subproject commit 2fad6f2f98c0df135e2306d32af18bb2796b852c
|
||||
Subproject commit cdef09114d2b43d2e461d066a5b56697ab567abc
|
|
@ -1 +1 @@
|
|||
Subproject commit de3276cc08ba13901d1f69060ff7501c1699bc4d
|
||||
Subproject commit bb9cb75e15b4bfce3063a94b40dfad2375d5605e
|
|
@ -1 +1 @@
|
|||
Subproject commit a90579e1e1e1c973e6ba8f6cf8e914d77fc8f0f2
|
||||
Subproject commit f9469d26ed9eb95d43982de88c035ac3862dd258
|
|
@ -1 +1 @@
|
|||
Subproject commit ddd26eb4abcd3c10ae5dd33b1345d10d58707995
|
||||
Subproject commit f3d504be1dc82cc4a8e4ea9b38bd5c2ce74d59ba
|
|
@ -1 +1 @@
|
|||
Subproject commit f6cdec74b64112016c459abe4a5d31a3b34caeb3
|
||||
Subproject commit 2ea025b1b68b0be95a0514732d4bc623f313fd75
|
|
@ -1 +1 @@
|
|||
Subproject commit a77f0f9c2e8f64568bbb68254d0134fbc7b5a8af
|
||||
Subproject commit b637c47423eb85233ba614424aadadace37fcfb1
|
|
@ -1 +1 @@
|
|||
Subproject commit 2fddabcaf0df1763111ed9dbf9e2d4cdb5b0434e
|
||||
Subproject commit 47cc91474823677218239b5b37901590755cac4c
|
|
@ -1 +1 @@
|
|||
Subproject commit 1e478b1530b3be81bd84f13620d0a23502d377f1
|
||||
Subproject commit a2491a806b636f66caf670527c49b864923f125c
|
|
@ -0,0 +1 @@
|
|||
Subproject commit b4a0461889ead5da69f4ed6d0118276b01613981
|
|
@ -1 +1 @@
|
|||
Subproject commit a9cf0cde77c185c6bbc79a3b6d77dd024a9683d2
|
||||
Subproject commit 72367f37cd221c7af7822ba3a9cd21cd3cd70292
|
|
@ -1 +1 @@
|
|||
Subproject commit acc4bdd73fdceb74d75cd5a1f261ae157ee32613
|
||||
Subproject commit a06c8a116e5767a8481b9018239fe729e01760a6
|
|
@ -1 +1 @@
|
|||
Subproject commit 2dfd61a0d5ffc8048e72d24e5ecdac9a74bb2bc3
|
||||
Subproject commit 5acf8a850d98789a79fe37836b2ac7b623d95913
|
|
@ -1 +1 @@
|
|||
Subproject commit 3d871907f0187c627277382f184209f5520703a6
|
||||
Subproject commit d3f9adce6e48d37222ef171a280cfa3122faf15b
|
|
@ -1 +1 @@
|
|||
Subproject commit 207953aac033d40728b5f8dd7fd73d90facbca5c
|
||||
Subproject commit df61e7b0be9dc0c6a1bbe60f526fbdc01b6c2819
|
|
@ -1 +1 @@
|
|||
Subproject commit 36d4a31010461e47f265553ebd764c69d38a254c
|
||||
Subproject commit 015eb1ccd5eb5364d8e1cf20358e7dcda9f12efc
|
|
@ -1 +1 @@
|
|||
Subproject commit bcfaae874fbae294ce04549d55b96d6b41603944
|
||||
Subproject commit 217af2bc7de658ff2f6380a066d99a149e69693e
|
|
@ -1 +1 @@
|
|||
Subproject commit 011acd627fc24342c397fc640b204a798f7b69dd
|
||||
Subproject commit 1c39469bac98eea022af695ac42e5096dae6130c
|
|
@ -1 +1 @@
|
|||
Subproject commit c58defd70947531c5a9c37ddcb569f240567a78b
|
||||
Subproject commit 74ea48f7a5d85591f5af804cacb57e9cfaab46c6
|
|
@ -1 +1 @@
|
|||
Subproject commit 742ac7c8fb52bb85d9fd367b60a7f80475d7ed14
|
||||
Subproject commit 13cdb9912ba31f6e267f1afb9f71fddf5b1c139c
|
|
@ -1 +1 @@
|
|||
Subproject commit 49ab415d6b601c99979262f9e91c21dcb3a927a7
|
||||
Subproject commit d1e8ac7ad9dcd65ab83749db3e5c96ffee80ebb7
|
|
@ -1 +1 @@
|
|||
Subproject commit 2e6b3f9feeacc678402454f7d3416b04a9a93e17
|
||||
Subproject commit b168b28fc58973cf20269cc87a655d7812659fd0
|
|
@ -1 +1 @@
|
|||
Subproject commit da02c76d4c802cd5abac73a5f274243b05e8cb35
|
||||
Subproject commit 332143d4ca5762d2d351ceb170c0b4e37dd42793
|
|
@ -1 +1 @@
|
|||
Subproject commit 5fdd62ab69fda70407644acc6f9b45681da9ef68
|
||||
Subproject commit 995959d5dca23fbe49590700d1aa26a96dca1df7
|
|
@ -1 +1 @@
|
|||
Subproject commit 272d225365eed46916390cf1f393dd08bc00b7d4
|
||||
Subproject commit d238fe99e24ea4cdb472f1d8a9c99dd189b0aeca
|
|
@ -1 +1 @@
|
|||
Subproject commit fad0f89e760829a76f553ef8459f61001597a846
|
||||
Subproject commit 632655b8f5f6f62e3b4d0b6161213634e0ae74e9
|
|
@ -1 +1 @@
|
|||
Subproject commit e86f258e43591ce4a04661277e77e9fdf6fec27e
|
||||
Subproject commit 3816a4f4c997b03d4a7ebfe35a617d1e50124b04
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 6757c5b37cf26458448930042cb0a41f8ad0a5ef
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c496cfb5768cd506d61100284fdab94dd439ec3b
|
|
@ -1 +1 @@
|
|||
Subproject commit 3aaf72165bc6ba10bf5219716c8654651649f87b
|
||||
Subproject commit 148345d232c83133de3649fb70b471f11501b3d2
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 6e8eedb1475e2b91f8dea7bceebb20e44d70b171
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 53f15602460329f69fef95498e6b8293aebb513a
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 4ba6956d49752f2d0cdc73903b86a34c225934ef
|
|
@ -1 +1 @@
|
|||
Subproject commit 837f3e5f16accae5b3677954921b5ddd517f0799
|
||||
Subproject commit 6452f2a78f32cf3b5d07e699f26d25e9c4d10d09
|
1003
locale/ID.po
1003
locale/ID.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1143
locale/cs.po
1143
locale/cs.po
File diff suppressed because it is too large
Load Diff
1148
locale/de_DE.po
1148
locale/de_DE.po
File diff suppressed because it is too large
Load Diff
739
locale/el.po
739
locale/el.po
File diff suppressed because it is too large
Load Diff
1122
locale/en_GB.po
1122
locale/en_GB.po
File diff suppressed because it is too large
Load Diff
1109
locale/es.po
1109
locale/es.po
File diff suppressed because it is too large
Load Diff
905
locale/fil.po
905
locale/fil.po
File diff suppressed because it is too large
Load Diff
1262
locale/fr.po
1262
locale/fr.po
File diff suppressed because it is too large
Load Diff
739
locale/hi.po
739
locale/hi.po
File diff suppressed because it is too large
Load Diff
931
locale/it_IT.po
931
locale/it_IT.po
File diff suppressed because it is too large
Load Diff
1007
locale/ja.po
1007
locale/ja.po
File diff suppressed because it is too large
Load Diff
776
locale/ko.po
776
locale/ko.po
File diff suppressed because it is too large
Load Diff
1057
locale/nl.po
1057
locale/nl.po
File diff suppressed because it is too large
Load Diff
972
locale/pl.po
972
locale/pl.po
File diff suppressed because it is too large
Load Diff
1139
locale/pt_BR.po
1139
locale/pt_BR.po
File diff suppressed because it is too large
Load Diff
983
locale/ru.po
983
locale/ru.po
File diff suppressed because it is too large
Load Diff
1135
locale/sv.po
1135
locale/sv.po
File diff suppressed because it is too large
Load Diff
782
locale/tr.po
782
locale/tr.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
42
main.c
42
main.c
|
@ -58,7 +58,7 @@
|
|||
#include "supervisor/shared/status_leds.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
#include "supervisor/shared/traceback.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
#include "supervisor/usb.h"
|
||||
#include "supervisor/workflow.h"
|
||||
|
@ -101,6 +101,10 @@
|
|||
#include "shared-module/memorymonitor/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_SOCKETPOOL
|
||||
#include "shared-bindings/socketpool/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
#include "shared-module/usb_hid/__init__.h"
|
||||
#endif
|
||||
|
@ -290,6 +294,16 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
|
|||
keypad_reset();
|
||||
#endif
|
||||
|
||||
// Close user-initiated sockets.
|
||||
#if CIRCUITPY_SOCKETPOOL
|
||||
socketpool_user_reset();
|
||||
#endif
|
||||
|
||||
// Turn off user initiated WiFi connections.
|
||||
#if CIRCUITPY_WIFI
|
||||
wifi_user_reset();
|
||||
#endif
|
||||
|
||||
// reset_board_buses() first because it may release pins from the never_reset state, so that
|
||||
// reset_port() can reset them.
|
||||
#if CIRCUITPY_BOARD
|
||||
|
@ -303,6 +317,9 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
|
|||
stop_mp();
|
||||
free_memory(heap);
|
||||
supervisor_move_memory();
|
||||
|
||||
// Let the workflows know we've reset in case they want to restart.
|
||||
supervisor_workflow_reset();
|
||||
}
|
||||
|
||||
STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
|
||||
|
@ -570,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();
|
||||
|
@ -684,6 +704,10 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
|
|||
vstr_t *boot_output;
|
||||
|
||||
STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
if (safe_mode == NO_HEAP) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If not in safe mode, run boot before initing USB and capture output in a file.
|
||||
|
||||
// There is USB setup to do even if boot.py is not actually run.
|
||||
|
@ -889,21 +913,7 @@ int __attribute__((used)) main(void) {
|
|||
|
||||
run_boot_py(safe_mode);
|
||||
|
||||
// Start USB after giving boot.py a chance to tweak behavior.
|
||||
#if CIRCUITPY_USB
|
||||
// Setup USB connection after heap is available.
|
||||
// It needs the heap to build descriptors.
|
||||
usb_init();
|
||||
#endif
|
||||
|
||||
// Set up any other serial connection.
|
||||
serial_init();
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
bleio_reset();
|
||||
supervisor_bluetooth_enable_workflow();
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
supervisor_workflow_start();
|
||||
|
||||
// Boot script is finished, so now go into REPL or run code.py.
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
|
|
|
@ -67,7 +67,7 @@ SRC_C += \
|
|||
shared/runtime/gchelper_generic.c \
|
||||
supervisor/stub/safe_mode.c \
|
||||
supervisor/stub/stack.c \
|
||||
supervisor/shared/translate.c
|
||||
supervisor/shared/translate/translate.c
|
||||
|
||||
# Add fmode when compiling with mingw gcc
|
||||
COMPILER_TARGET := $(shell $(CC) -dumpmachine)
|
||||
|
@ -78,6 +78,6 @@ endif
|
|||
OBJ = $(PY_CORE_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
|
||||
$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h
|
||||
$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compression.generated.h
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
||||
|
|
|
@ -123,8 +123,6 @@ $(echo PERIPHERALS_CHIP_FAMILY=$(PERIPHERALS_CHIP_FAMILY))
|
|||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -ggdb3 -Og -Os
|
||||
# You may want to disable -flto if it interferes with debugging.
|
||||
CFLAGS += -flto -flto-partition=none
|
||||
# You may want to enable these flags to make setting breakpoints easier.
|
||||
# CFLAGS += -fno-inline -fno-ipa-sra
|
||||
ifeq ($(CHIP_FAMILY), samd21)
|
||||
|
@ -147,8 +145,6 @@ else
|
|||
CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT)
|
||||
endif
|
||||
|
||||
CFLAGS += -flto -flto-partition=none
|
||||
|
||||
ifeq ($(CIRCUITPY_FULL_BUILD),0)
|
||||
CFLAGS += --param inline-unit-growth=15 --param max-inline-insns-auto=20
|
||||
endif
|
||||
|
@ -204,7 +200,6 @@ endif
|
|||
CFLAGS += -Wno-stringop-overread -Wno-stringop-overflow
|
||||
|
||||
LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs
|
||||
LDFLAGS += -flto=$(shell $(NPROC))
|
||||
LIBS := -lgcc -lc
|
||||
|
||||
# Use toolchain libm if we're not using our own.
|
||||
|
@ -275,6 +270,9 @@ SRC_ASF += \
|
|||
hpl/oscctrl/hpl_oscctrl.c \
|
||||
hpl/trng/hpl_trng.c \
|
||||
|
||||
# Ignore these errors
|
||||
$(BUILD)/asf4/same54/hpl/sercom/hpl_sercom.o: CFLAGS += -Wno-maybe-uninitialized
|
||||
|
||||
else ifeq ($(CHIP_FAMILY), same51)
|
||||
SRC_ASF += \
|
||||
hal/src/hal_rand_sync.c \
|
||||
|
|
|
@ -9,6 +9,3 @@ CHIP_FAMILY = samd21
|
|||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
LONGINT_IMPL = NONE
|
||||
CIRCUITPY_FULL_BUILD = 0
|
||||
|
||||
# This board has many pins, and we have to remove something else to make room.
|
||||
CIRCUITPY_RAINBOWIO = 0
|
||||
|
|
|
@ -11,4 +11,3 @@ LONGINT_IMPL = NONE
|
|||
CIRCUITPY_FULL_BUILD = 0
|
||||
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_RAINBOWIO = 0
|
||||
|
|
|
@ -19,7 +19,7 @@ CIRCUITPY_COUNTIO = 1
|
|||
CIRCUITPY_BUSDEVICE = 1
|
||||
|
||||
# Include these Python libraries in firmware.
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground/frozen_cpx
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
|
||||
|
|
|
@ -18,7 +18,7 @@ CIRCUITPY_KEYPAD = 0
|
|||
CIRCUITPY_ONEWIREIO = 0
|
||||
|
||||
# Include these Python libraries in firmware.
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground/frozen_cpx
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Crickit
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor
|
||||
|
|
|
@ -12,6 +12,7 @@ EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C"
|
|||
# Turn off features and optimizations for displayio build to make room for additional frozen libs.
|
||||
LONGINT_IMPL = NONE
|
||||
CIRCUITPY_KEYPAD = 0
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
|
@ -23,7 +24,7 @@ CIRCUITPY_BITMAPTOOLS = 0
|
|||
CIRCUITPY_PARALLELDISPLAY = 0
|
||||
|
||||
# Include these Python libraries in firmware.
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground/frozen_cpx
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Thermistor
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "supervisor/board.h"
|
||||
#include "mpconfigboard.h"
|
||||
#include "hal/include/hal_gpio.h"
|
||||
|
||||
void board_init(void) {
|
||||
}
|
||||
|
||||
bool board_requests_safe_mode(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void reset_board(void) {
|
||||
}
|
||||
|
||||
void board_deinit(void) {
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#define MICROPY_HW_BOARD_NAME "Cytron Maker Zero SAMD21"
|
||||
#define MICROPY_HW_MCU_NAME "samd21g18"
|
||||
|
||||
#define MICROPY_HW_LED_TX &pin_PA27
|
||||
#define MICROPY_HW_LED_RX &pin_PB03
|
||||
|
||||
#define DEFAULT_I2C_BUS_SCL (&pin_PA23)
|
||||
#define DEFAULT_I2C_BUS_SDA (&pin_PA22)
|
||||
|
||||
#define DEFAULT_SPI_BUS_SCK (&pin_PB11)
|
||||
#define DEFAULT_SPI_BUS_MOSI (&pin_PB10)
|
||||
#define DEFAULT_SPI_BUS_MISO (&pin_PA12)
|
||||
|
||||
#define DEFAULT_UART_BUS_RX (&pin_PA11)
|
||||
#define DEFAULT_UART_BUS_TX (&pin_PA10)
|
||||
|
||||
// USB is always used internally so skip the pin objects for it.
|
||||
#define IGNORE_PIN_PA24 1
|
||||
#define IGNORE_PIN_PA25 1
|
||||
|
||||
// Connected to a crystal
|
||||
#define IGNORE_PIN_PA00 1
|
||||
#define IGNORE_PIN_PA01 1
|
||||
|
||||
// SWD-only
|
||||
#define IGNORE_PIN_PA30 1
|
||||
#define IGNORE_PIN_PA31 1
|
|
@ -0,0 +1,11 @@
|
|||
USB_VID = 0x04D8
|
||||
USB_PID = 0xE799
|
||||
USB_PRODUCT = "Maker Zero SAMD21"
|
||||
USB_MANUFACTURER = "Cytron"
|
||||
|
||||
CHIP_VARIANT = SAMD21G18A
|
||||
CHIP_FAMILY = samd21
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
LONGINT_IMPL = NONE
|
||||
CIRCUITPY_FULL_BUILD = 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue