Merge pull request #4 from adafruit/main
Pull in the latest main branch from adafruit
This commit is contained in:
commit
21857ed9be
31
.devcontainer/Readme.md
Normal file
31
.devcontainer/Readme.md
Normal file
@ -0,0 +1,31 @@
|
||||
Build CircuitPython in a Github-Devcontainer
|
||||
============================================
|
||||
|
||||
To build CircuitPython within a Github-Devcontainer, you need to perform
|
||||
the following steps.
|
||||
|
||||
1. checkout the code to a devcontainer
|
||||
|
||||
- click on the green "<> Code"-button
|
||||
- select the Codespaces-tab
|
||||
- choose "+ new with options..." from the "..."-menu
|
||||
- in the following screen select the branch and then
|
||||
- select ".devcontainer/cortex-m/devcontainer.json" instead
|
||||
of "Default Codespaces configuration"
|
||||
- update region as necessary
|
||||
- finally, click on the green "Create codespace" button
|
||||
|
||||
2. Your codespace is created. Cloning the images is quite fast, but
|
||||
preparing it for CircuitPython-development takes about 10 minutes.
|
||||
Note that this is a one-time task.
|
||||
|
||||
3. During creation, you can run the command
|
||||
`tail -f /workspaces/.codespaces/.persistedshare/creation.log`
|
||||
to see what is going on.
|
||||
|
||||
4. To actually build CircuitPython, run
|
||||
|
||||
cd ports/raspberrypi
|
||||
make -j $(nproc) BOARD=whatever TRANSLATION=xx_XX
|
||||
|
||||
This takes about 2m40s.
|
23
.devcontainer/cortex-m/devcontainer.json
Normal file
23
.devcontainer/cortex-m/devcontainer.json
Normal file
@ -0,0 +1,23 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
||||
{
|
||||
"name": "CircuitPython Cortex-M Build-Environment (base: Default Linux Universal)",
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
|
||||
"postCreateCommand": ".devcontainer/cortex-m/on-create.sh",
|
||||
"remoteEnv": { "PATH": "/workspaces/gcc-arm-none-eabi/bin:${containerEnv:PATH}" }
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "uname -a",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
59
.devcontainer/cortex-m/on-create.sh
Executable file
59
.devcontainer/cortex-m/on-create.sh
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# -----------------------------------------------------------------------------
|
||||
# on-create.sh: postCreateCommand-hook for devcontainer.json (Cortex-M build)
|
||||
#
|
||||
# Author: Bernhard Bablok
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
echo -e "[on-create.sh] downloading and installing gcc-arm-non-eabi toolchain"
|
||||
cd /workspaces
|
||||
wget -qO gcc-arm-none-eabi.tar.bz2 https://adafru.it/Pid
|
||||
tar -xjf gcc-arm-none-eabi.tar.bz2
|
||||
ln -s gcc-arm-none-eabi-10-2020-q4-major gcc-arm-none-eabi
|
||||
rm -f /workspaces/gcc-arm-none-eabi.tar.bz2
|
||||
export PATH=/workspaces/gcc-arm-none-eabi/bin:$PATH
|
||||
|
||||
# add repository and install tools
|
||||
echo -e "[on-create.sh] adding pybricks/ppa"
|
||||
sudo add-apt-repository -y ppa:pybricks/ppa
|
||||
echo -e "[on-create.sh] installing uncrustify and mtools"
|
||||
sudo apt-get -y install uncrustify mtools
|
||||
|
||||
# dosfstools >= 4.2 needed, standard repo only has 4.1
|
||||
echo -e "[on-create.sh] downloading and installing dosfstools"
|
||||
wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz
|
||||
tar -xzf dosfstools-4.2.tar.gz
|
||||
cd dosfstools-4.2/
|
||||
./configure
|
||||
make -j $(nproc)
|
||||
sudo make install
|
||||
cd /workspaces
|
||||
rm -fr /workspaces/dosfstools-4.2 /workspaces/dosfstools-4.2.tar.gz
|
||||
|
||||
# prepare source-code tree
|
||||
cd /workspaces/circuitpython/
|
||||
echo -e "[on-create.sh] fetching submodules"
|
||||
make fetch-submodules
|
||||
echo -e "[on-create.sh] fetching tags"
|
||||
git fetch --tags --recurse-submodules=no --shallow-since="2021-07-01" https://github.com/adafruit/circuitpython HEAD
|
||||
|
||||
# additional python requirements
|
||||
echo -e "[on-create.sh] pip-installing requirements"
|
||||
pip install --upgrade -r requirements-dev.txt
|
||||
pip install --upgrade -r requirements-doc.txt
|
||||
|
||||
# add pre-commit
|
||||
echo -e "[on-create.sh] installing pre-commit"
|
||||
pre-commit install
|
||||
|
||||
# create cross-compiler
|
||||
echo -e "[on-create.sh] building mpy-cross"
|
||||
make -j $(nproc) -C mpy-cross # time: about 36 sec
|
||||
|
||||
# that's it!
|
||||
echo -e "[on-create.sh] setup complete"
|
||||
|
||||
#commands to actually build CP:
|
||||
#cd ports/raspberrypi
|
||||
#time make -j $(nproc) BOARD=pimoroni_tufty2040 TRANSLATION=de_DE
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -6,7 +6,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >-
|
||||
Thanks! for testing out CircuitPython. Now that you have encountered a
|
||||
Thanks for testing out CircuitPython! Now that you have encountered a
|
||||
bug... you can file a report for it.
|
||||
- type: textarea
|
||||
id: firmware
|
||||
|
61
.github/actions/deps/external/action.yml
vendored
Normal file
61
.github/actions/deps/external/action.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: Fetch external deps
|
||||
|
||||
inputs:
|
||||
action:
|
||||
required: false
|
||||
default: restore
|
||||
type: choice
|
||||
options:
|
||||
- cache
|
||||
- restore
|
||||
|
||||
port:
|
||||
required: false
|
||||
default: none
|
||||
type: string
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# arm
|
||||
- name: Get arm toolchain
|
||||
if: >-
|
||||
inputs.port != 'none' &&
|
||||
inputs.port != 'litex' &&
|
||||
inputs.port != 'espressif'
|
||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
with:
|
||||
release: '10-2020-q4'
|
||||
|
||||
# espressif
|
||||
- name: Get espressif toolchain
|
||||
if: inputs.port == 'espressif'
|
||||
run: sudo apt-get install -y ninja-build
|
||||
shell: bash
|
||||
- name: Install IDF tools
|
||||
if: inputs.port == 'espressif'
|
||||
run: |
|
||||
echo "Installing ESP-IDF tools"
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install required
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install cmake
|
||||
echo "Installing Python environment and packages"
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install-python-env
|
||||
rm -rf $IDF_TOOLS_PATH/dist
|
||||
shell: bash
|
||||
- name: Set environment
|
||||
if: inputs.port == 'espressif'
|
||||
run: |
|
||||
source $IDF_PATH/export.sh
|
||||
echo >> $GITHUB_ENV "IDF_PYTHON_ENV_PATH=$IDF_PYTHON_ENV_PATH"
|
||||
echo >> $GITHUB_PATH "$PATH"
|
||||
shell: bash
|
||||
|
||||
# common
|
||||
- name: Cache python dependencies
|
||||
if: inputs.port != 'espressif'
|
||||
uses: ./.github/actions/deps/python
|
||||
with:
|
||||
action: ${{ inputs.action }}
|
||||
- name: Install python dependencies
|
||||
run: pip install -r requirements-dev.txt
|
||||
shell: bash
|
36
.github/actions/deps/ports/action.yml
vendored
Normal file
36
.github/actions/deps/ports/action.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
name: Fetch port deps
|
||||
|
||||
inputs:
|
||||
board:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
outputs:
|
||||
port:
|
||||
value: ${{ steps.board-to-port.outputs.port }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Board to port
|
||||
id: board-to-port
|
||||
run: |
|
||||
PORT=$(find ports/*/boards/ -type d -name ${{ inputs.board }} | sed 's/^ports\///g;s/\/boards.*//g')
|
||||
if [ -z $PORT ]; then (exit 1); else echo >> $GITHUB_OUTPUT "port=$PORT"; fi
|
||||
shell: bash
|
||||
|
||||
- name: Set up broadcom
|
||||
if: steps.board-to-port.outputs.port == 'broadcom'
|
||||
uses: ./.github/actions/deps/ports/broadcom
|
||||
|
||||
- name: Set up espressif
|
||||
if: steps.board-to-port.outputs.port == 'espressif'
|
||||
uses: ./.github/actions/deps/ports/espressif
|
||||
|
||||
- name: Set up litex
|
||||
if: steps.board-to-port.outputs.port == 'litex'
|
||||
uses: ./.github/actions/deps/ports/litex
|
||||
|
||||
- name: Set up nrf
|
||||
if: steps.board-to-port.outputs.port == 'nrf'
|
||||
uses: ./.github/actions/deps/ports/nrf
|
21
.github/actions/deps/ports/broadcom/action.yml
vendored
Normal file
21
.github/actions/deps/ports/broadcom/action.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Fetch broadcom port deps
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Get broadcom toolchain
|
||||
run: |
|
||||
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
|
||||
sudo apt-get install -y mtools
|
||||
shell: bash
|
||||
- name: Install mkfs.fat
|
||||
run: |
|
||||
wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz
|
||||
tar -xaf dosfstools-4.2.tar.gz
|
||||
cd dosfstools-4.2
|
||||
./configure
|
||||
make -j 2
|
||||
cd src
|
||||
echo >> $GITHUB_PATH $(pwd)
|
||||
shell: bash
|
36
.github/actions/deps/ports/espressif/action.yml
vendored
Normal file
36
.github/actions/deps/ports/espressif/action.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
name: Fetch espressif port deps
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set IDF env
|
||||
run: |
|
||||
echo >> $GITHUB_ENV "IDF_PATH=$GITHUB_WORKSPACE/ports/espressif/esp-idf"
|
||||
echo >> $GITHUB_ENV "IDF_TOOLS_PATH=$GITHUB_WORKSPACE/.idf_tools"
|
||||
shell: bash
|
||||
|
||||
- name: Get IDF commit
|
||||
id: idf-commit
|
||||
run: |
|
||||
COMMIT=$(git submodule status ports/espressif/esp-idf | grep -o -P '(?<=^-).*(?= )')
|
||||
echo "$COMMIT"
|
||||
echo "commit=$COMMIT" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
- name: Cache IDF submodules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
.git/modules/ports/espressif/esp-idf
|
||||
ports/espressif/esp-idf
|
||||
key: submodules-idf-${{ steps.idf-commit.outputs.commit }}
|
||||
|
||||
- name: Cache IDF tools
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ env.IDF_TOOLS_PATH }}
|
||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-idf-${{ steps.idf-commit.outputs.commit }}
|
||||
|
||||
- name: Initialize IDF submodules
|
||||
run: git submodule update --init --depth=1 --recursive $IDF_PATH
|
||||
shell: bash
|
10
.github/actions/deps/ports/litex/action.yml
vendored
Normal file
10
.github/actions/deps/ports/litex/action.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
name: Fetch litex port deps
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Get litex toolchain
|
||||
run: |
|
||||
wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz
|
||||
sudo tar -C /usr --strip-components=1 -xaf riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz
|
||||
shell: bash
|
17
.github/actions/deps/ports/nrf/action.yml
vendored
Normal file
17
.github/actions/deps/ports/nrf/action.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: Fetch nrf port deps
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Get nrfutil 7+
|
||||
run: |
|
||||
wget https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil
|
||||
chmod +x nrfutil
|
||||
./nrfutil install nrf5sdk-tools
|
||||
mkdir -p $HOME/.local/bin
|
||||
mv nrfutil $HOME/.local/bin
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Print nrfutil version
|
||||
run: nrfutil -V
|
||||
shell: bash
|
42
.github/actions/deps/python/action.yml
vendored
Normal file
42
.github/actions/deps/python/action.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Fetch python deps
|
||||
|
||||
inputs:
|
||||
action:
|
||||
description: The cache action to use
|
||||
required: false
|
||||
default: restore
|
||||
type: choice
|
||||
options:
|
||||
- cache
|
||||
- restore
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Cache python dependencies
|
||||
id: cache-python-deps
|
||||
if: inputs.action == 'cache'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .cp_tools
|
||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
||||
|
||||
- name: Restore python dependencies
|
||||
id: restore-python-deps
|
||||
if: inputs.action == 'restore'
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: .cp_tools
|
||||
key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }}
|
||||
|
||||
- name: Set up venv
|
||||
if: inputs.action == 'cache' && !steps.cache-python-deps.outputs.cache-hit
|
||||
run: python -m venv .cp_tools
|
||||
shell: bash
|
||||
|
||||
- name: Activate venv
|
||||
if: inputs.action == 'cache' || (inputs.action == 'restore' && steps.restore-python-deps.outputs.cache-hit)
|
||||
run: |
|
||||
source .cp_tools/bin/activate
|
||||
echo >> $GITHUB_PATH "$PATH"
|
||||
shell: bash
|
87
.github/actions/deps/submodules/action.yml
vendored
Normal file
87
.github/actions/deps/submodules/action.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
name: 'Fetch Submodules'
|
||||
|
||||
inputs:
|
||||
target:
|
||||
description: 'The target for ci_fetch_deps'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
submodules:
|
||||
description: 'The submodules to cache'
|
||||
required: false
|
||||
default: '["extmod/ulab", "lib/", "tools/"]'
|
||||
type: string
|
||||
|
||||
action:
|
||||
description: 'The cache action to use'
|
||||
required: false
|
||||
default: 'restore'
|
||||
type: choice
|
||||
options:
|
||||
- cache
|
||||
- restore
|
||||
|
||||
version:
|
||||
description: 'Whether to generate CP version'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
outputs:
|
||||
frozen:
|
||||
description: 'Whether frozen submodules were fetched'
|
||||
value: ${{ steps.cp-deps.outputs.frozen_tags }}
|
||||
|
||||
version:
|
||||
description: 'The CP version'
|
||||
value: ${{ steps.cp-version.outputs.cp-version }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Create submodule status
|
||||
id: create-submodule-status
|
||||
run: |
|
||||
git submodule status ${{ join(fromJSON(inputs.submodules), ' ') }} >> submodule_status
|
||||
echo $(cut -d ' ' -f 2 submodule_status) | echo "submodules=[\"$(sed "s/ /\", \"/g")\"]" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
- name: Cache submodules
|
||||
if: ${{ inputs.action == 'cache' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
||||
key: submodules-common-${{ hashFiles('submodule_status') }}
|
||||
enableCrossOsArchive: true
|
||||
|
||||
- name: Restore submodules
|
||||
if: ${{ inputs.action == 'restore' }}
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}"
|
||||
key: submodules-common-${{ hashFiles('submodule_status') }}
|
||||
enableCrossOsArchive: true
|
||||
|
||||
- name: Remove submodule status
|
||||
run: rm submodule_status
|
||||
shell: bash
|
||||
|
||||
- name: CircuitPython dependencies
|
||||
id: cp-deps
|
||||
run: python tools/ci_fetch_deps.py ${{ inputs.target || matrix.board || github.job }}
|
||||
shell: bash
|
||||
|
||||
- name: CircuitPython version
|
||||
id: cp-version
|
||||
if: ${{ inputs.version == 'true' }}
|
||||
run: |
|
||||
echo "::group::Fetch history and tags"
|
||||
git fetch --no-recurse-submodules --shallow-since="2021-07-01" --tags https://github.com/adafruit/circuitpython HEAD
|
||||
git fetch --no-recurse-submodules --shallow-since="2021-07-01" origin $GITHUB_SHA
|
||||
git repack -d
|
||||
echo "::endgroup::"
|
||||
CP_VERSION=$(tools/describe)
|
||||
echo "$CP_VERSION"
|
||||
echo "CP_VERSION=$CP_VERSION" >> $GITHUB_ENV
|
||||
echo "cp-version=$CP_VERSION" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
37
.github/actions/mpy_cross/action.yml
vendored
Normal file
37
.github/actions/mpy_cross/action.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Set up mpy-cross
|
||||
|
||||
inputs:
|
||||
download:
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Download mpy-cross
|
||||
id: download-mpy-cross
|
||||
if: inputs.download == 'true'
|
||||
continue-on-error: true
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: mpy-cross
|
||||
path: mpy-cross
|
||||
|
||||
- name: Make mpy-cross executable
|
||||
if: inputs.download == 'true' && steps.download-mpy-cross.outcome == 'success'
|
||||
run: sudo chmod +x mpy-cross/mpy-cross
|
||||
shell: bash
|
||||
|
||||
- name: Build mpy-cross
|
||||
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
||||
run: make -C mpy-cross -j2
|
||||
shell: bash
|
||||
|
||||
- name: Upload mpy-cross
|
||||
if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure'
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy-cross
|
||||
path: mpy-cross/mpy-cross
|
33
.github/actions/upload_aws/action.yml
vendored
Normal file
33
.github/actions/upload_aws/action.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Upload to AWS S3
|
||||
|
||||
inputs:
|
||||
source:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
destination:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
AWS_ACCESS_KEY_ID:
|
||||
required: true
|
||||
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Upload to S3
|
||||
if: >-
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') ||
|
||||
(github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
run: >-
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] ||
|
||||
aws s3 cp ${{ inputs.source }} s3://adafruit-circuit-python/bin/${{ inputs.destination }}
|
||||
${{ endsWith(inputs.source, '/') && '--recursive' || '' }} --no-progress --region us-east-1
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ inputs.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ inputs.AWS_SECRET_ACCESS_KEY }}
|
||||
shell: bash
|
84
.github/workflows/build-boards.yml
vendored
Normal file
84
.github/workflows/build-boards.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
name: Build boards
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
boards:
|
||||
required: true
|
||||
type: string
|
||||
cp-version:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
required: false
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
board:
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
CP_VERSION: ${{ inputs.cp-version }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(inputs.boards) }}
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Set up port
|
||||
id: set-up-port
|
||||
uses: ./.github/actions/deps/ports
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
- name: Set up submodules
|
||||
id: set-up-submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
- name: Set up external
|
||||
uses: ./.github/actions/deps/external
|
||||
with:
|
||||
port: ${{ steps.set-up-port.outputs.port }}
|
||||
- name: Set up mpy-cross
|
||||
if: steps.set-up-submodules.outputs.frozen == 'True'
|
||||
uses: ./.github/actions/mpy_cross
|
||||
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
python3 --version
|
||||
cmake --version || true
|
||||
ninja --version || true
|
||||
aarch64-none-elf-gcc --version || true
|
||||
arm-none-eabi-gcc --version || true
|
||||
xtensa-esp32-elf-gcc --version || true
|
||||
riscv32-esp-elf-gcc --version || true
|
||||
riscv64-unknown-elf-gcc --version || true
|
||||
mkfs.fat --version || true
|
||||
|
||||
- name: Set up build failure matcher
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
|
||||
- name: Build board
|
||||
run: python3 -u build_release_files.py
|
||||
working-directory: tools
|
||||
env:
|
||||
BOARDS: ${{ matrix.board }}
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: bin/${{ matrix.board }}
|
||||
- name: Upload to S3
|
||||
uses: ./.github/actions/upload_aws
|
||||
with:
|
||||
source: bin/
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
70
.github/workflows/build-mpy-cross.yml
vendored
Normal file
70
.github/workflows/build-mpy-cross.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
name: Build mpy-cross
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cp-version:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
required: false
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mpy-cross: ["static", "static-aarch64", "static-mingw", "static-raspbian"]
|
||||
env:
|
||||
CP_VERSION: ${{ inputs.cp-version }}
|
||||
EX_static-mingw: static.exe
|
||||
OS_static: linux-amd64
|
||||
OS_static-aarch64: linux-aarch64
|
||||
OS_static-mingw: windows
|
||||
OS_static-raspbian: linux-raspbian
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
with:
|
||||
target: mpy-cross
|
||||
|
||||
- name: Install toolchain (aarch64)
|
||||
if: matrix.mpy-cross == 'static-aarch64'
|
||||
run: sudo apt-get install -y gcc-aarch64-linux-gnu
|
||||
- name: Install toolchain (mingw)
|
||||
if: matrix.mpy-cross == 'static-mingw'
|
||||
run: sudo apt-get install -y mingw-w64
|
||||
|
||||
- name: Build mpy-cross.${{ matrix.mpy-cross }}
|
||||
run: make -C mpy-cross -j2 -f Makefile.${{ matrix.mpy-cross }}
|
||||
|
||||
- name: Set output
|
||||
run: |
|
||||
echo >> $GITHUB_ENV "EX=${{ env[format('EX_{0}', matrix.mpy-cross)] || matrix.mpy-cross }}"
|
||||
echo >> $GITHUB_ENV "OS=${{ env[format('OS_{0}', matrix.mpy-cross)] }}"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy-cross.${{ env.EX }}
|
||||
path: mpy-cross/mpy-cross.${{ env.EX }}
|
||||
- name: Upload to S3
|
||||
uses: ./.github/actions/upload_aws
|
||||
with:
|
||||
source: mpy-cross/mpy-cross.${{ env.EX }}
|
||||
destination: mpy-cross/${{ env.OS }}/mpy-cross-${{ env.OS }}-${{ env.CP_VERSION }}.${{ env.EX }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
606
.github/workflows/build.yml
vendored
606
.github/workflows/build.yml
vendored
@ -17,156 +17,107 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-20.04
|
||||
scheduler:
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
build-doc: ${{ steps.set-matrix.outputs.build-doc }}
|
||||
boards-arm: ${{ steps.set-matrix.outputs.boards-arm }}
|
||||
boards-riscv: ${{ steps.set-matrix.outputs.boards-riscv }}
|
||||
boards-espressif: ${{ steps.set-matrix.outputs.boards-espressif }}
|
||||
boards-aarch: ${{ steps.set-matrix.outputs.boards-aarch }}
|
||||
docs: ${{ steps.set-matrix.outputs.docs }}
|
||||
ports: ${{ steps.set-matrix.outputs.ports }}
|
||||
windows: ${{ steps.set-matrix.outputs.windows }}
|
||||
cp-version: ${{ steps.set-up-submodules.outputs.version }}
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py test ${{ github.sha }}
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y eatmydata
|
||||
sudo eatmydata apt-get install -y gettext gcc-aarch64-linux-gnu mingw-w64
|
||||
pip install -r requirements-ci.txt -r requirements-dev.txt
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
python3 --version
|
||||
- name: Duplicate USB VID/PID Check
|
||||
python-version: 3.x
|
||||
- name: Duplicate USB VID/PID check
|
||||
run: python3 -u -m tools.ci_check_duplicate_usb_vid_pid
|
||||
- name: Build mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Build unix port
|
||||
run: |
|
||||
make -C ports/unix VARIANT=coverage -j2
|
||||
- name: Test all
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1
|
||||
working-directory: tests
|
||||
- name: Print failure info
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --print-failures
|
||||
if: failure()
|
||||
working-directory: tests
|
||||
- name: Native Tests
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --emit native
|
||||
working-directory: tests
|
||||
- name: mpy Tests
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --via-mpy -d basics float micropython
|
||||
working-directory: tests
|
||||
- name: Native mpy Tests
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py -j1 --via-mpy --emit native -d basics float micropython
|
||||
working-directory: tests
|
||||
- name: Build native modules
|
||||
run: |
|
||||
make -C examples/natmod/features1
|
||||
make -C examples/natmod/features2
|
||||
make -C examples/natmod/btree
|
||||
make -C examples/natmod/framebuf
|
||||
make -C examples/natmod/uheapq
|
||||
make -C examples/natmod/urandom
|
||||
make -C examples/natmod/ure
|
||||
make -C examples/natmod/uzlib
|
||||
- name: Test native modules
|
||||
run: MICROPY_CPYTHON3=python3.8 MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py
|
||||
working-directory: tests
|
||||
- name: Build mpy-cross.static-aarch64
|
||||
run: make -C mpy-cross -j2 -f Makefile.static-aarch64
|
||||
- uses: actions/upload-artifact@v2
|
||||
- name: Set up submodules
|
||||
id: set-up-submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
with:
|
||||
name: mpy-cross.static-aarch64
|
||||
path: mpy-cross/mpy-cross.static-aarch64
|
||||
- name: Build mpy-cross.static-raspbian
|
||||
run: make -C mpy-cross -j2 -f Makefile.static-raspbian
|
||||
- uses: actions/upload-artifact@v2
|
||||
action: cache
|
||||
version: true
|
||||
- name: Set up external
|
||||
uses: ./.github/actions/deps/external
|
||||
with:
|
||||
name: mpy-cross.static-raspbian
|
||||
path: mpy-cross/mpy-cross.static-raspbian
|
||||
- name: Build mpy-cross.static
|
||||
run: make -C mpy-cross -j2 -f Makefile.static
|
||||
- uses: actions/upload-artifact@v2
|
||||
action: cache
|
||||
- name: Set up mpy-cross
|
||||
uses: ./.github/actions/mpy_cross
|
||||
with:
|
||||
name: mpy-cross.static-amd64-linux
|
||||
path: mpy-cross/mpy-cross.static
|
||||
- name: Build mpy-cross.static-mingw
|
||||
run: make -C mpy-cross -j2 -f Makefile.static-mingw
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mpy-cross.static-x64-windows
|
||||
path: mpy-cross/mpy-cross.static.exe
|
||||
- name: Upload mpy-cross builds to S3
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static-aarch64 s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-aarch64-${{ env.CP_VERSION }} --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static-raspbian s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-raspbian-${{ env.CP_VERSION }} --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-amd64-linux-${{ env.CP_VERSION }} --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross.static.exe s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross.static-x64-windows-${{ env.CP_VERSION }}.exe --no-progress --region us-east-1
|
||||
- name: "Get changes"
|
||||
download: false
|
||||
- name: Get last commit with checks
|
||||
id: get-last-commit-with-checks
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
list-files: json
|
||||
filters: |
|
||||
changed:
|
||||
- '**'
|
||||
- name: "Set matrix"
|
||||
working-directory: tools
|
||||
run: python3 -u ci_changes_per_commit.py
|
||||
env:
|
||||
REPO: ${{ github.repository }}
|
||||
PULL: ${{ github.event.number }}
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
EXCLUDE_COMMIT: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Set head sha
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
|
||||
- name: Set base sha
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
git fetch --no-tags --no-recurse-submodules --depth=$((DEPTH + 1)) origin $HEAD_SHA
|
||||
echo "BASE_SHA=$(git rev-list $HEAD_SHA --skip=$DEPTH --max-count=1)" >> $GITHUB_ENV
|
||||
env:
|
||||
DEPTH: ${{ steps.get-last-commit-with-checks.outputs.commit_depth || github.event.pull_request.commits }}
|
||||
- name: Get changes
|
||||
id: get-changes
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo $(git diff $BASE_SHA...$HEAD_SHA --name-only) | echo "changed_files=[\"$(sed "s/ /\", \"/g")\"]" >> $GITHUB_OUTPUT
|
||||
- name: Set matrix
|
||||
id: set-matrix
|
||||
working-directory: tools
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.filter.outputs.changed_files }}
|
||||
run: python3 -u ci_set_matrix.py
|
||||
env:
|
||||
CHANGED_FILES: ${{ steps.get-changes.outputs.changed_files }}
|
||||
LAST_FAILED_JOBS: ${{ steps.get-last-commit-with-checks.outputs.check_runs }}
|
||||
|
||||
tests:
|
||||
needs: scheduler
|
||||
uses: ./.github/workflows/run-tests.yml
|
||||
with:
|
||||
cp-version: ${{ needs.scheduler.outputs.cp-version }}
|
||||
|
||||
mpy-cross:
|
||||
needs: scheduler
|
||||
if: needs.scheduler.outputs.ports != '{}'
|
||||
uses: ./.github/workflows/build-mpy-cross.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
cp-version: ${{ needs.scheduler.outputs.cp-version }}
|
||||
|
||||
mpy-cross-mac:
|
||||
runs-on: macos-10.15
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
runs-on: macos-11
|
||||
needs: scheduler
|
||||
if: needs.scheduler.outputs.ports != '{}'
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py mpy-cross-mac ${{ github.sha }}
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install gettext
|
||||
echo >>$GITHUB_PATH /usr/local/opt/gettext/bin
|
||||
python-version: 3.x
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
@ -174,89 +125,84 @@ jobs:
|
||||
msgfmt --version
|
||||
- name: Build mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy-cross-macos-catalina
|
||||
name: mpy-cross-macos-11-x64
|
||||
path: mpy-cross/mpy-cross
|
||||
- name: Select SDK for M1 build
|
||||
run: sudo xcode-select -switch /Applications/Xcode_12.3.app
|
||||
- name: Build mpy-cross (arm64)
|
||||
run: make -C mpy-cross -j2 -f Makefile.m1 V=2
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy-cross-macos-bigsur-arm64
|
||||
name: mpy-cross-macos-11-arm64
|
||||
path: mpy-cross/mpy-cross-arm64
|
||||
- name: Make universal binary
|
||||
run: lipo -create -output mpy-cross-macos-universal mpy-cross/mpy-cross mpy-cross/mpy-cross-arm64
|
||||
- uses: actions/upload-artifact@v2
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: mpy-cross-macos-universal
|
||||
name: mpy-cross-macos-11-universal
|
||||
path: mpy-cross-macos-universal
|
||||
- name: Upload mpy-cross build to S3
|
||||
- name: Upload to S3
|
||||
if: >-
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') ||
|
||||
(github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
run: |
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-universal-${{ env.CP_VERSION }} --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-bigsur-${{ env.CP_VERSION }}-arm64 --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/mpy-cross-macos-catalina-${{ env.CP_VERSION }} --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/macos-11/mpy-cross-macos-11-${{ env.CP_VERSION }}-universal --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/macos-11/mpy-cross-macos-11-${{ env.CP_VERSION }}-arm64 --no-progress --region us-east-1
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/macos-11/mpy-cross-macos-11-${{ env.CP_VERSION }}-x64 --no-progress --region us-east-1
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
|
||||
|
||||
build-doc:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
if: ${{ needs.test.outputs.build-doc == 'True' }}
|
||||
docs:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: scheduler
|
||||
if: needs.scheduler.outputs.docs == 'True'
|
||||
env:
|
||||
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2.2.0
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py docs ${{ github.sha }}
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
python-version: 3.x
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y eatmydata
|
||||
sudo eatmydata apt-get install -y latexmk librsvg2-bin texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra
|
||||
pip install -r requirements-ci.txt -r requirements-doc.txt
|
||||
sudo apt-get install -y latexmk librsvg2-bin texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra
|
||||
pip install -r requirements-doc.txt
|
||||
- name: Build and Validate Stubs
|
||||
run: make check-stubs -j2
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: stubs
|
||||
path: circuitpython-stubs/dist/*
|
||||
- name: Test Documentation Build (HTML)
|
||||
run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs
|
||||
path: _build/html
|
||||
- name: Test Documentation Build (LaTeX/PDF)
|
||||
run: |
|
||||
make latexpdf
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs
|
||||
path: _build/latex
|
||||
- name: Upload stubs to S3
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
- name: Upload to S3
|
||||
uses: ./.github/actions/upload_aws
|
||||
with:
|
||||
source: circuitpython-stubs/dist/*.tar.gz
|
||||
destination: stubs/circuitpython-stubs-${{ env.CP_VERSION }}.tar.gz
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
zip -9r circuitpython-stubs.zip circuitpython-stubs
|
||||
[ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp circuitpython-stubs/dist/*.tar.gz s3://adafruit-circuit-python/bin/stubs/circuitpython-stubs-${{ env.CP_VERSION }}.zip --no-progress --region us-east-1
|
||||
- name: Upload stubs to PyPi
|
||||
if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')
|
||||
env:
|
||||
@ -267,263 +213,83 @@ jobs:
|
||||
[ -z "$TWINE_USERNAME" ] || echo "Uploading dev release to PyPi"
|
||||
[ -z "$TWINE_USERNAME" ] || twine upload circuitpython-stubs/dist/*
|
||||
|
||||
|
||||
build-arm:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(needs.test.outputs.boards-arm) }}
|
||||
if: ${{ needs.test.outputs.boards-arm != '[]' }}
|
||||
windows:
|
||||
runs-on: windows-2022
|
||||
needs: scheduler
|
||||
if: needs.scheduler.outputs.windows == 'True'
|
||||
env:
|
||||
CP_VERSION: ${{ needs.scheduler.outputs.cp-version }}
|
||||
defaults:
|
||||
run:
|
||||
# We define a custom shell script here, although `msys2.cmd` does neither exist nor is it available in the PATH yet
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
with:
|
||||
submodules: false
|
||||
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
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
arm-none-eabi-gcc --version
|
||||
python3 --version
|
||||
- name: mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Setup build failure matcher
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
|
||||
- name: build
|
||||
run: python3 -u build_release_files.py
|
||||
working-directory: tools
|
||||
env:
|
||||
BOARDS: ${{ matrix.board }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: bin/${{ matrix.board }}
|
||||
- name: Upload to S3
|
||||
run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1"
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
|
||||
|
||||
build-riscv:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(needs.test.outputs.boards-riscv) }}
|
||||
if: ${{ needs.test.outputs.boards-riscv != '[]' }}
|
||||
steps:
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get install -y gettext
|
||||
pip install -r requirements-ci.txt -r requirements-dev.txt
|
||||
wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz
|
||||
sudo tar -C /usr --strip-components=1 -xaf riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
riscv64-unknown-elf-gcc --version
|
||||
python3 --version
|
||||
- name: mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Setup build failure matcher
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
|
||||
- name: build
|
||||
run: python3 -u build_release_files.py
|
||||
working-directory: tools
|
||||
env:
|
||||
BOARDS: ${{ matrix.board }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: bin/${{ matrix.board }}
|
||||
- name: Upload to S3
|
||||
run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1"
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
|
||||
|
||||
build-espressif:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(needs.test.outputs.boards-espressif) }}
|
||||
if: ${{ needs.test.outputs.boards-espressif != '[]' }}
|
||||
steps:
|
||||
- name: Set up Python 3
|
||||
id: py3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }}
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
- uses: actions/cache@v2
|
||||
name: Fetch IDF tool cache
|
||||
id: idf-cache
|
||||
with:
|
||||
path: ${{ github.workspace }}/.idf_tools
|
||||
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)
|
||||
env:
|
||||
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
|
||||
- name: Install IDF tools
|
||||
run: |
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install required
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install cmake
|
||||
$IDF_PATH/tools/idf_tools.py --non-interactive install-python-env
|
||||
rm -rf $IDF_TOOLS_PATH/dist
|
||||
env:
|
||||
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
|
||||
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source $IDF_PATH/export.sh
|
||||
sudo apt-get install -y gettext ninja-build
|
||||
pip install -r requirements-ci.txt -r requirements-dev.txt
|
||||
env:
|
||||
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
|
||||
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
|
||||
- name: Versions
|
||||
run: |
|
||||
source $IDF_PATH/export.sh
|
||||
gcc --version
|
||||
xtensa-esp32s2-elf-gcc --version
|
||||
python3 --version
|
||||
ninja --version
|
||||
cmake --version
|
||||
# We want to change the configuration of the git command that actions/checkout will be using
|
||||
# (since it is not possible to set autocrlf through the action yet, see actions/checkout#226).
|
||||
- run: git config --global core.autocrlf input
|
||||
shell: bash
|
||||
env:
|
||||
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
|
||||
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
|
||||
- name: mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Setup build failure matcher
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
|
||||
- name: build
|
||||
- name: Check python coding (cmd)
|
||||
run: python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
shell: cmd
|
||||
# We use a JS Action, which calls the system terminal or other custom terminals directly, if required
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
install: base-devel git wget unzip gcc python-pip
|
||||
# The goal of this was to test how things worked when the default file encoding (locale.getpreferedencoding())
|
||||
# was not UTF-8. However, msys2 python does use utf-8 as the preferred file encoding, and using actions/setup-python
|
||||
# python3.8 gave a broken build, so we're not really testing what we wanted to test.
|
||||
# However, commandline length limits are being tested so that does some good.
|
||||
- name: Check python coding (msys2)
|
||||
run: |
|
||||
source $IDF_PATH/export.sh
|
||||
python3 -u build_release_files.py
|
||||
working-directory: tools
|
||||
shell: bash
|
||||
env:
|
||||
IDF_PATH: ${{ github.workspace }}/ports/espressif/esp-idf
|
||||
IDF_TOOLS_PATH: ${{ github.workspace }}/.idf_tools
|
||||
BOARDS: ${{ matrix.board }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: bin/${{ matrix.board }}
|
||||
- name: Upload to S3
|
||||
run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1"
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
|
||||
build-aarch:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: ${{ fromJSON(needs.test.outputs.boards-aarch) }}
|
||||
if: ${{ needs.test.outputs.boards-aarch != '[]' }}
|
||||
steps:
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
locale -v
|
||||
which python; python --version
|
||||
python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
which python3; python3 --version
|
||||
python3 -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
wget --no-verbose -O gcc-arm.zip https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-win32.zip
|
||||
unzip -q -d /tmp gcc-arm.zip
|
||||
tar -C /tmp/gcc-arm-none-* -cf - . | tar -C /usr/local -xf -
|
||||
pip install wheel
|
||||
# requirements_dev.txt doesn't install on windows. (with msys2 python)
|
||||
# instead, pick a subset for what we want to do
|
||||
pip install cascadetoml jinja2 typer click intelhex
|
||||
# check that installed packages work....?
|
||||
which python; python --version; python -c "import cascadetoml"
|
||||
which python3; python3 --version; python3 -c "import cascadetoml"
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py ${{ matrix.board }} ${{ github.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get install -y gettext mtools
|
||||
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
|
||||
- uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
- name: build mpy-cross
|
||||
run: make -j2 -C mpy-cross
|
||||
- name: build rp2040
|
||||
run: make -j2 -C ports/raspberrypi BOARD=adafruit_feather_rp2040 TRANSLATION=de_DE
|
||||
- name: build samd21
|
||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m0_express TRANSLATION=zh_Latn_pinyin
|
||||
- name: build samd51
|
||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m4_express TRANSLATION=es
|
||||
- name: build nrf
|
||||
run: make -j2 -C ports/nrf BOARD=feather_nrf52840_express TRANSLATION=fr
|
||||
- name: build stm
|
||||
run: make -j2 -C ports/stm BOARD=feather_stm32f405_express TRANSLATION=pt_BR
|
||||
# I gave up trying to do esp builds on windows when I saw
|
||||
# ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported
|
||||
# https://github.com/espressif/esp-idf/issues/7062
|
||||
|
||||
ports:
|
||||
needs: [scheduler, mpy-cross, tests]
|
||||
if: needs.scheduler.outputs.ports != '{}'
|
||||
uses: ./.github/workflows/build-boards.yml
|
||||
secrets: inherit
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
port: ${{ fromJSON(needs.scheduler.outputs.ports).ports }}
|
||||
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
|
||||
tar -xaf dosfstools-4.2.tar.gz
|
||||
cd dosfstools-4.2
|
||||
./configure
|
||||
make -j 2
|
||||
cd src
|
||||
echo >>$GITHUB_PATH $(pwd)
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
aarch64-none-elf-gcc --version
|
||||
arm-none-eabi-gcc --version
|
||||
python3 --version
|
||||
mkfs.fat --version || true
|
||||
- name: mpy-cross
|
||||
run: make -C mpy-cross -j2
|
||||
- name: Setup build failure matcher
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/workflows/match-build-fail.json"
|
||||
- name: build
|
||||
run: python3 -u build_release_files.py
|
||||
working-directory: tools
|
||||
env:
|
||||
BOARDS: ${{ matrix.board }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.board }}
|
||||
path: bin/${{ matrix.board }}
|
||||
- name: Upload to S3
|
||||
run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/ s3://adafruit-circuit-python/bin/ --recursive --no-progress --region us-east-1"
|
||||
env:
|
||||
AWS_PAGER: ''
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested'))
|
||||
boards: ${{ toJSON(fromJSON(needs.scheduler.outputs.ports)[matrix.port]) }}
|
||||
cp-version: ${{ needs.scheduler.outputs.cp-version }}
|
||||
|
@ -6,41 +6,38 @@ name: Update CircuitPython.org
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
types: [published, rerequested]
|
||||
|
||||
jobs:
|
||||
website:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v2.2.0
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py website ${{ github.sha }}
|
||||
- name: Install deps
|
||||
run: |
|
||||
pip install -r requirements-dev.txt
|
||||
python-version: 3.x
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
with:
|
||||
version: true
|
||||
- name: Set up external
|
||||
uses: ./.github/actions/deps/external
|
||||
- name: Versions
|
||||
run: |
|
||||
gcc --version
|
||||
python3 --version
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
- name: Website
|
||||
run: python3 build_board_info.py
|
||||
working-directory: tools
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
||||
ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }}
|
||||
if: github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')
|
89
.github/workflows/custom-board-build.yml
vendored
Normal file
89
.github/workflows/custom-board-build.yml
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
name: Custom board build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
board:
|
||||
description: 'Board: Found in ports/*/boards/[board_id]'
|
||||
required: true
|
||||
type: string
|
||||
version:
|
||||
description: 'Version: Can be a tag or a commit (>=8.1.0)'
|
||||
required: false
|
||||
default: latest
|
||||
type: string
|
||||
language:
|
||||
description: 'Language: Found in locale/[language].po'
|
||||
required: false
|
||||
default: en_US
|
||||
type: string
|
||||
flags:
|
||||
description: 'Flags: Build flags (e.g. CIRCUITPY_WIFI=1)'
|
||||
required: false
|
||||
type: string
|
||||
debug:
|
||||
description: 'Make a debug build'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
run-name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ inputs.flags != '' && '-custom' || '' }}${{ inputs.debug && '-debug' || '' }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up repository
|
||||
run: |
|
||||
git clone --filter=tree:0 https://github.com/adafruit/circuitpython.git $GITHUB_WORKSPACE
|
||||
git checkout ${{ inputs.version == 'latest' && 'HEAD' || inputs.version }}
|
||||
- name: Set up identifier
|
||||
if: inputs.debug || inputs.flags != ''
|
||||
run: |
|
||||
> custom-build && git add custom-build
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Set up port
|
||||
id: set-up-port
|
||||
uses: ./.github/actions/deps/ports
|
||||
with:
|
||||
board: ${{ inputs.board }}
|
||||
- name: Set up submodules
|
||||
id: set-up-submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
with:
|
||||
action: cache
|
||||
target: ${{ inputs.board }}
|
||||
- name: Set up external
|
||||
uses: ./.github/actions/deps/external
|
||||
with:
|
||||
action: cache
|
||||
port: ${{ steps.set-up-port.outputs.port }}
|
||||
- name: Set up mpy-cross
|
||||
if: steps.set-up-submodules.outputs.frozen == 'True'
|
||||
uses: ./.github/actions/mpy_cross
|
||||
with:
|
||||
download: false
|
||||
- name: Versions
|
||||
run: |
|
||||
tools/describe
|
||||
gcc --version
|
||||
python3 --version
|
||||
cmake --version || true
|
||||
ninja --version || true
|
||||
aarch64-none-elf-gcc --version || true
|
||||
arm-none-eabi-gcc --version || true
|
||||
xtensa-esp32-elf-gcc --version || true
|
||||
riscv32-esp-elf-gcc --version || true
|
||||
riscv64-unknown-elf-gcc --version || true
|
||||
mkfs.fat --version || true
|
||||
- name: Build board
|
||||
run: make -j2 ${{ inputs.flags }} BOARD=${{ inputs.board }} DEBUG=${{ inputs.debug && '1' || '0' }} TRANSLATION=${{ inputs.language }}
|
||||
working-directory: ports/${{ steps.set-up-port.outputs.port }}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ inputs.flags != '' && '-custom' || '' }}${{ inputs.debug && '-debug' || '' }}
|
||||
path: ports/${{ steps.set-up-port.outputs.port }}/build-${{ inputs.board }}/firmware.*
|
18
.github/workflows/notify-on-issue-label.yml
vendored
Normal file
18
.github/workflows/notify-on-issue-label.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Notify users based on issue labels
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: tekktrik/issue-labeled-ping@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
user: v923z
|
||||
label: ulab
|
||||
message: Heads up {user} - the "{label}" label was applied to this issue.
|
14
.github/workflows/notify.yml
vendored
14
.github/workflows/notify.yml
vendored
@ -1,14 +0,0 @@
|
||||
name: Notify users based on issue labels
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jenschelkopf/issue-label-notification-action@1.3
|
||||
with:
|
||||
recipients: |
|
||||
ulab=@v923z
|
112
.github/workflows/ports_windows.yml
vendored
112
.github/workflows/ports_windows.yml
vendored
@ -1,112 +0,0 @@
|
||||
name: windows port
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/*.yml'
|
||||
- 'extmod/**'
|
||||
- 'lib/**'
|
||||
- 'mpy-cross/**'
|
||||
- 'ports/unix/**'
|
||||
- 'ports/windows/**'
|
||||
- 'py/**'
|
||||
- 'requirements*.txt'
|
||||
- 'tools/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2019
|
||||
defaults:
|
||||
run:
|
||||
# We define a custom shell script here, although `msys2.cmd` does neither exist nor is it available in the PATH yet
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
|
||||
# We want to change the configuration of the git command that actions/checkout will be using (since it is not possible to set autocrlf through the action yet, see actions/checkout#226).
|
||||
- run: git config --global core.autocrlf input
|
||||
shell: bash
|
||||
|
||||
- name: Check python coding (cmd)
|
||||
run: |
|
||||
python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
shell: cmd
|
||||
|
||||
# We use a JS Action, which calls the system terminal or other custom terminals directly, if required
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
install: base-devel git wget unzip gcc python-pip
|
||||
|
||||
# The goal of this was to test how things worked when the default file
|
||||
# encoding (locale.getpreferedencoding()) was not UTF-8. However, msys2
|
||||
# python does use utf-8 as the preferred file encoding, and using
|
||||
# actions/setup-python python3.8 gave a broken build, so we're not really
|
||||
# testing what we wanted to test.
|
||||
#
|
||||
# however, commandline length limits are being tested so that does some
|
||||
# good.
|
||||
- name: Check python coding (msys2)
|
||||
run: |
|
||||
locale -v
|
||||
which python; python --version
|
||||
python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
which python3; python3 --version
|
||||
python3 -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
wget --no-verbose -O gcc-arm.zip https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-win32.zip
|
||||
unzip -q -d /tmp gcc-arm.zip
|
||||
tar -C /tmp/gcc-arm-none-* -cf - . | tar -C /usr/local -xf -
|
||||
pip install wheel
|
||||
# requirements_dev.txt doesn't install on windows. (with msys2 python)
|
||||
# instead, pick a subset for what we want to do
|
||||
pip install cascadetoml jinja2 typer click intelhex
|
||||
# check that installed packages work....?
|
||||
which python; python --version; python -c "import cascadetoml"
|
||||
which python3; python3 --version; python3 -c "import cascadetoml"
|
||||
|
||||
- uses: actions/checkout@v2.2.0
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Get CP deps
|
||||
run: python tools/ci_fetch_deps.py windows ${{ github.sha }}
|
||||
- name: CircuitPython version
|
||||
run: |
|
||||
tools/describe || git log --parents HEAD~4..
|
||||
echo >>$GITHUB_ENV CP_VERSION=$(tools/describe)
|
||||
|
||||
- name: build mpy-cross
|
||||
run: make -j2 -C mpy-cross
|
||||
|
||||
- name: build rp2040
|
||||
run: make -j2 -C ports/raspberrypi BOARD=adafruit_feather_rp2040 TRANSLATION=de_DE
|
||||
|
||||
- name: build samd21
|
||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m0_express TRANSLATION=zh_Latn_pinyin
|
||||
|
||||
- name: build samd51
|
||||
run: make -j2 -C ports/atmel-samd BOARD=feather_m4_express TRANSLATION=es
|
||||
|
||||
- name: build nrf
|
||||
run: make -j2 -C ports/nrf BOARD=feather_nrf52840_express TRANSLATION=fr
|
||||
|
||||
- name: build stm
|
||||
run: make -j2 -C ports/stm BOARD=feather_stm32f405_express TRANSLATION=pt_BR
|
||||
|
||||
# I gave up trying to do esp32 builds on windows when I saw
|
||||
# ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported
|
||||
# https://github.com/espressif/esp-idf/issues/7062
|
||||
#
|
||||
# - name: prepare esp
|
||||
# run: ports/espressif/esp-idf/install.bat
|
||||
# shell: cmd
|
||||
#
|
||||
# - name: build esp
|
||||
# run: . ports/espressif/esp-idf/export.sh && make -j2 -C ports/espressif BOARD=adafruit_metro_esp32s2
|
36
.github/workflows/pre-commit.yml
vendored
36
.github/workflows/pre-commit.yml
vendored
@ -14,33 +14,31 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2.2.0
|
||||
- name: Set up Python 3
|
||||
uses: actions/setup-python@v2
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt-add-repository -y -u ppa:pybricks/ppa
|
||||
sudo apt-get install -y gettext uncrustify
|
||||
pip3 install black polib pyyaml
|
||||
- name: Populate selected submodules
|
||||
run: git submodule update --init extmod/ulab
|
||||
- name: Set PY
|
||||
run: echo >>$GITHUB_ENV PY="$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')"
|
||||
- uses: actions/cache@v2
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
- uses: pre-commit/action@v1.1.0
|
||||
python-version: 3.x
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
- name: Set up external
|
||||
uses: ./.github/actions/deps/external
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y gettext uncrustify
|
||||
- name: Run pre-commit
|
||||
uses: pre-commit/action@v3.0.0
|
||||
- name: Make patch
|
||||
if: failure()
|
||||
run: git diff > ~/pre-commit.patch
|
||||
- name: Upload patch
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: patch
|
||||
path: ~/pre-commit.patch
|
||||
|
67
.github/workflows/run-tests.yml
vendored
Normal file
67
.github/workflows/run-tests.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
name: Run tests
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
cp-version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test: [all, mpy, native, native_mpy]
|
||||
env:
|
||||
CP_VERSION: ${{ inputs.cp-version }}
|
||||
MICROPY_CPYTHON3: python3.8
|
||||
MICROPY_MICROPYTHON: ../ports/unix/micropython-coverage
|
||||
TEST_all:
|
||||
TEST_mpy: --via-mpy -d basics float micropython
|
||||
TEST_native: --emit native
|
||||
TEST_native_mpy: --via-mpy --emit native -d basics float micropython
|
||||
steps:
|
||||
- name: Set up repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
fetch-depth: 1
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Set up submodules
|
||||
uses: ./.github/actions/deps/submodules
|
||||
with:
|
||||
target: tests
|
||||
- name: Set up external
|
||||
if: matrix.test == 'all'
|
||||
uses: ./.github/actions/deps/external
|
||||
- name: Set up mpy-cross
|
||||
uses: ./.github/actions/mpy_cross
|
||||
- name: Build unix port
|
||||
run: make -C ports/unix VARIANT=coverage -j2
|
||||
- name: Run tests
|
||||
run: ./run-tests.py -j2 ${{ env[format('TEST_{0}', matrix.test)] }}
|
||||
working-directory: tests
|
||||
- name: Print failure info
|
||||
run: ./run-tests.py -j2 --print-failures
|
||||
if: failure()
|
||||
working-directory: tests
|
||||
- name: Build native modules
|
||||
if: matrix.test == 'all'
|
||||
run: |
|
||||
make -C examples/natmod/features1
|
||||
make -C examples/natmod/features2
|
||||
make -C examples/natmod/btree
|
||||
make -C examples/natmod/framebuf
|
||||
make -C examples/natmod/uheapq
|
||||
make -C examples/natmod/urandom
|
||||
make -C examples/natmod/ure
|
||||
make -C examples/natmod/uzlib
|
||||
- name: Test native modules
|
||||
if: matrix.test == 'all'
|
||||
run: ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py
|
||||
working-directory: tests
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
!atmel-samd/asf/**/*.a
|
||||
*.elf
|
||||
*.bin
|
||||
!*.toml.bin
|
||||
*.map
|
||||
*.hex
|
||||
*.dis
|
||||
|
32
.gitmodules
vendored
32
.gitmodules
vendored
@ -146,9 +146,9 @@
|
||||
[submodule "ports/espressif/esp-idf"]
|
||||
path = ports/espressif/esp-idf
|
||||
url = https://github.com/adafruit/esp-idf.git
|
||||
branch = circuitpython8
|
||||
branch = release/v4.4-circuitpython
|
||||
[submodule "ports/espressif/certificates/nina-fw"]
|
||||
path = ports/espressif/certificates/nina-fw
|
||||
path = lib/certificates/nina-fw
|
||||
url = https://github.com/adafruit/nina-fw.git
|
||||
[submodule "frozen/Adafruit_CircuitPython_ST7789"]
|
||||
path = frozen/Adafruit_CircuitPython_ST7789
|
||||
@ -187,10 +187,6 @@
|
||||
[submodule "frozen/Adafruit_CircuitPython_APDS9960"]
|
||||
path = frozen/Adafruit_CircuitPython_APDS9960
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_APDS9960
|
||||
[submodule "ports/broadcom/peripherals"]
|
||||
path = ports/broadcom/peripherals
|
||||
url = https://github.com/adafruit/broadcom-peripherals.git
|
||||
branch = main-build
|
||||
[submodule "rpi-firmware"]
|
||||
path = ports/broadcom/firmware
|
||||
url = https://github.com/raspberrypi/rpi-firmware.git
|
||||
@ -307,3 +303,27 @@
|
||||
[submodule "frozen/circuitpython_picoed"]
|
||||
path = frozen/circuitpython_picoed
|
||||
url = https://github.com/elecfreaks/circuitpython_picoed.git
|
||||
[submodule "ports/espressif/esp32-camera"]
|
||||
path = ports/espressif/esp32-camera
|
||||
url = https://github.com/adafruit/esp32-camera/
|
||||
branch = circuitpython
|
||||
[submodule "ports/raspberrypi/lib/cyw43-driver"]
|
||||
path = ports/raspberrypi/lib/cyw43-driver
|
||||
url = https://github.com/georgerobotics/cyw43-driver.git
|
||||
[submodule "ports/raspberrypi/lib/lwip"]
|
||||
path = ports/raspberrypi/lib/lwip
|
||||
url = https://github.com/adafruit/lwip.git
|
||||
branch = circuitpython8
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
[submodule "frozen/Adafruit_CircuitPython_UC8151D"]
|
||||
path = frozen/Adafruit_CircuitPython_UC8151D
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_UC8151D
|
||||
[submodule "frozen/Adafruit_CircuitPython_SSD1680"]
|
||||
path = frozen/Adafruit_CircuitPython_SSD1680
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_SSD1680
|
||||
[submodule "ports/broadcom/peripherals"]
|
||||
path = ports/broadcom/peripherals
|
||||
url = https://github.com/adafruit/broadcom-peripherals.git
|
||||
branch = main-build
|
||||
|
@ -10,7 +10,7 @@ repos:
|
||||
- id: end-of-file-fixer
|
||||
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)'
|
||||
- id: trailing-whitespace
|
||||
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*)'
|
||||
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)'
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: translations
|
||||
|
@ -14,7 +14,7 @@ build:
|
||||
python: "3"
|
||||
jobs:
|
||||
post_install:
|
||||
- python tools/ci_fetch_deps.py docs HEAD
|
||||
- python tools/ci_fetch_deps.py build-doc
|
||||
|
||||
formats:
|
||||
- pdf
|
||||
|
@ -35,6 +35,8 @@ Failing to install these will prevent from properly building.
|
||||
|
||||
pip3 install -r requirements-dev.txt
|
||||
|
||||
If you run into an error installing minify_html, you may need to install `rust`.
|
||||
|
||||
### mpy-cross
|
||||
|
||||
As part of the build process, mpy-cross is needed to compile .py files into .mpy files.
|
||||
|
76
LICENSE
76
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2022 Damien P. George
|
||||
Copyright (c) 2013-2022 Damien P. George and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -9,77 +9,13 @@ 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 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.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Unless specified otherwise (see below), the above license and copyright applies
|
||||
to all files in this repository.
|
||||
|
||||
Individual files may include additional copyright holders.
|
||||
|
||||
The various ports of MicroPython may include third-party software that is
|
||||
licensed under different terms. These licenses are summarised in the tree
|
||||
below, please refer to these files and directories for further license and
|
||||
copyright information. Note that (L)GPL-licensed code listed below is only
|
||||
used during the build process and is not part of the compiled source code.
|
||||
|
||||
/ (MIT)
|
||||
/drivers
|
||||
/cc3000 (BSD-3-clause)
|
||||
/cc3100 (BSD-3-clause)
|
||||
/wiznet5k (BSD-3-clause)
|
||||
/lib
|
||||
/asf4 (Apache-2.0)
|
||||
/axtls (BSD-3-clause)
|
||||
/config
|
||||
/scripts
|
||||
/config (GPL-2.0-or-later)
|
||||
/Rules.mak (GPL-2.0)
|
||||
/berkeley-db-1xx (BSD-4-clause)
|
||||
/btstack (See btstack/LICENSE)
|
||||
/cmsis (BSD-3-clause)
|
||||
/crypto-algorithms (NONE)
|
||||
/libhydrogen (ISC)
|
||||
/littlefs (BSD-3-clause)
|
||||
/lwip (BSD-3-clause)
|
||||
/mynewt-nimble (Apache-2.0)
|
||||
/nrfx (BSD-3-clause)
|
||||
/nxp_driver (BSD-3-Clause)
|
||||
/oofatfs (BSD-1-clause)
|
||||
/pico-sdk (BSD-3-clause)
|
||||
/re15 (BSD-3-clause)
|
||||
/stm32lib (BSD-3-clause)
|
||||
/tinytest (BSD-3-clause)
|
||||
/tinyusb (MIT)
|
||||
/uzlib (Zlib)
|
||||
/logo (uses OFL-1.1)
|
||||
/ports
|
||||
/cc3200
|
||||
/hal (BSD-3-clause)
|
||||
/simplelink (BSD-3-clause)
|
||||
/FreeRTOS (GPL-2.0 with FreeRTOS exception)
|
||||
/stm32
|
||||
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
|
||||
/stm32_it.* (MIT + BSD-3-clause)
|
||||
/system_stm32*.c (MIT + BSD-3-clause)
|
||||
/boards
|
||||
/startup_stm32*.s (BSD-3-clause)
|
||||
/*/stm32*.h (BSD-3-clause)
|
||||
/usbdev (MCD-ST Liberty SW License Agreement V2)
|
||||
/usbhost (MCD-ST Liberty SW License Agreement V2)
|
||||
/teensy
|
||||
/core (PJRC.COM)
|
||||
/zephyr
|
||||
/src (Apache-2.0)
|
||||
/tools
|
||||
/dfu.py (LGPL-3.0-only)
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
85
LICENSE_MicroPython
Normal file
85
LICENSE_MicroPython
Normal file
@ -0,0 +1,85 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2022 Damien P. George
|
||||
|
||||
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.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Unless specified otherwise (see below), the above license and copyright applies
|
||||
to all files in this repository.
|
||||
|
||||
Individual files may include additional copyright holders.
|
||||
|
||||
The various ports of MicroPython may include third-party software that is
|
||||
licensed under different terms. These licenses are summarised in the tree
|
||||
below, please refer to these files and directories for further license and
|
||||
copyright information. Note that (L)GPL-licensed code listed below is only
|
||||
used during the build process and is not part of the compiled source code.
|
||||
|
||||
/ (MIT)
|
||||
/drivers
|
||||
/cc3000 (BSD-3-clause)
|
||||
/cc3100 (BSD-3-clause)
|
||||
/wiznet5k (BSD-3-clause)
|
||||
/lib
|
||||
/asf4 (Apache-2.0)
|
||||
/axtls (BSD-3-clause)
|
||||
/config
|
||||
/scripts
|
||||
/config (GPL-2.0-or-later)
|
||||
/Rules.mak (GPL-2.0)
|
||||
/berkeley-db-1xx (BSD-4-clause)
|
||||
/btstack (See btstack/LICENSE)
|
||||
/cmsis (BSD-3-clause)
|
||||
/crypto-algorithms (NONE)
|
||||
/libhydrogen (ISC)
|
||||
/littlefs (BSD-3-clause)
|
||||
/lwip (BSD-3-clause)
|
||||
/mynewt-nimble (Apache-2.0)
|
||||
/nrfx (BSD-3-clause)
|
||||
/nxp_driver (BSD-3-Clause)
|
||||
/oofatfs (BSD-1-clause)
|
||||
/pico-sdk (BSD-3-clause)
|
||||
/re15 (BSD-3-clause)
|
||||
/stm32lib (BSD-3-clause)
|
||||
/tinytest (BSD-3-clause)
|
||||
/tinyusb (MIT)
|
||||
/uzlib (Zlib)
|
||||
/logo (uses OFL-1.1)
|
||||
/ports
|
||||
/cc3200
|
||||
/hal (BSD-3-clause)
|
||||
/simplelink (BSD-3-clause)
|
||||
/FreeRTOS (GPL-2.0 with FreeRTOS exception)
|
||||
/stm32
|
||||
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
|
||||
/stm32_it.* (MIT + BSD-3-clause)
|
||||
/system_stm32*.c (MIT + BSD-3-clause)
|
||||
/boards
|
||||
/startup_stm32*.s (BSD-3-clause)
|
||||
/*/stm32*.h (BSD-3-clause)
|
||||
/usbdev (MCD-ST Liberty SW License Agreement V2)
|
||||
/usbhost (MCD-ST Liberty SW License Agreement V2)
|
||||
/teensy
|
||||
/core (PJRC.COM)
|
||||
/zephyr
|
||||
/src (Apache-2.0)
|
||||
/tools
|
||||
/dfu.py (LGPL-3.0-only)
|
9
Makefile
9
Makefile
@ -90,7 +90,7 @@ clean:
|
||||
rm -rf autoapi
|
||||
rm -rf $(STUBDIR) $(DISTDIR) *.egg-info
|
||||
|
||||
html: stubs
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
@ -323,10 +323,11 @@ clean-nrf:
|
||||
clean-stm:
|
||||
$(MAKE) -C ports/stm BOARD=feather_stm32f405_express clean
|
||||
|
||||
|
||||
# This update will fail because the commits we need aren't the latest on the
|
||||
# branch. We can ignore that though because we fix it with the second command.
|
||||
# (Only works for git servers that allow sha fetches.)
|
||||
.PHONY: fetch-submodules
|
||||
fetch-submodules:
|
||||
# This update will fail because the commits we need aren't the latest on the
|
||||
# branch. We can ignore that though because we fix it with the second command.
|
||||
# (Only works for git servers that allow sha fetches.)
|
||||
git submodule update --init -N --depth 1 || true
|
||||
git submodule foreach 'git fetch --tags --depth 1 origin $$sha1 && git checkout -q $$sha1'
|
||||
|
34
README.rst
34
README.rst
@ -84,17 +84,19 @@ common set of requirements.
|
||||
|
||||
If you'd like to use the term "CircuitPython" and Blinka for your product here is what we ask:
|
||||
|
||||
* Your product is supported by the primary
|
||||
- Your product is supported by the primary
|
||||
`"adafruit/circuitpython" <https://github.com/adafruit/circuitpython>`_ repo. This way we can
|
||||
update any custom code as we update the CircuitPython internals.
|
||||
* Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source
|
||||
- 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 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.
|
||||
- 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
|
||||
@ -136,6 +138,16 @@ Behavior
|
||||
- Adds a safe mode that does not run user code after a hard crash or brown out. This makes it
|
||||
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.
|
||||
- Safe mode may be handled programmatically by providing a ``safemode.py``.
|
||||
``safemode.py`` is run if the board has reset due to entering safe mode, unless the safe mode
|
||||
initiated by the user by pressing button(s).
|
||||
USB is not available so nothing can be printed.
|
||||
``safemode.py`` can determine why the safe mode occurred
|
||||
using ``supervisor.runtime.safe_mode_reason``, and take appropriate action. For instance,
|
||||
if a hard crash occurred, ``safemode.py`` may do a ``microcontroller.reset()``
|
||||
to automatically restart despite the crash.
|
||||
If the battery is low, but is being charged, ``safemode.py`` may put the board in deep sleep
|
||||
for a while. Or it may simply reset, and have ``code.py`` check the voltage and do the sleep.
|
||||
- RGB status LED indicating CircuitPython state.
|
||||
- One green flash - code completed without error.
|
||||
- Two red flashes - code ended due to an exception.
|
||||
@ -143,9 +155,9 @@ Behavior
|
||||
- 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``,
|
||||
``main.txt``
|
||||
- Boot is one of these: ``boot.py``, ``boot.txt``
|
||||
- ``code.py`` may also be named``code.txt``, ``main.py``, or ``main.txt``.
|
||||
- ``boot.py`` may also be named ``boot.txt``.
|
||||
- ``safemode.py`` may also be named ``safemode.txt``.
|
||||
|
||||
API
|
||||
~~~
|
||||
@ -218,7 +230,7 @@ Supported Support status
|
||||
================ ============================================================
|
||||
atmel-samd ``SAMD21`` stable | ``SAMD51`` stable
|
||||
cxd56 stable
|
||||
espressif ``ESP32-C3`` beta | ``ESP32-S2`` stable | ``ESP32-S3`` beta
|
||||
espressif ``ESP32`` beta | ``ESP32-C3`` beta | ``ESP32-S2`` stable | ``ESP32-S3`` beta
|
||||
litex alpha
|
||||
mimxrt10xx alpha
|
||||
nrf stable
|
||||
|
26
conf.py
26
conf.py
@ -33,25 +33,6 @@ 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.
|
||||
@ -71,8 +52,8 @@ subprocess.check_output(["make", "stubs"])
|
||||
#modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards()
|
||||
modules_support_matrix = shared_bindings_matrix.support_matrix_by_board()
|
||||
modules_support_matrix_reverse = defaultdict(list)
|
||||
for board, modules in modules_support_matrix.items():
|
||||
for module in modules[0]:
|
||||
for board, matrix_info in modules_support_matrix.items():
|
||||
for module in matrix_info["modules"]:
|
||||
modules_support_matrix_reverse[module].append(board)
|
||||
|
||||
modules_support_matrix_reverse = dict(
|
||||
@ -190,6 +171,7 @@ exclude_patterns = ["**/build*",
|
||||
".env",
|
||||
".venv",
|
||||
".direnv",
|
||||
".devcontainer/Readme.md",
|
||||
"data",
|
||||
"docs/autoapi",
|
||||
"docs/README.md",
|
||||
@ -218,6 +200,7 @@ exclude_patterns = ["**/build*",
|
||||
"ports/cxd56/spresense-exported-sdk",
|
||||
"ports/espressif/certificates",
|
||||
"ports/espressif/esp-idf",
|
||||
"ports/espressif/esp32-camera",
|
||||
"ports/espressif/.idf_tools",
|
||||
"ports/espressif/peripherals",
|
||||
"ports/litex/hw",
|
||||
@ -231,6 +214,7 @@ exclude_patterns = ["**/build*",
|
||||
"ports/nrf/peripherals",
|
||||
"ports/nrf/usb",
|
||||
"ports/raspberrypi/sdk",
|
||||
"ports/raspberrypi/lib",
|
||||
"ports/stm/st_driver",
|
||||
"ports/stm/packages",
|
||||
"ports/stm/peripherals",
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd
|
||||
Subproject commit 73fafcbe4c66b23df63be31e9227353b695abb08
|
@ -49,8 +49,8 @@
|
||||
#include "shared-bindings/_bleio/ScanEntry.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
|
||||
#if CIRCUITPY_DOTENV
|
||||
#include "shared-module/dotenv/__init__.h"
|
||||
#if CIRCUITPY_OS_GETENV
|
||||
#include "shared-bindings/os/__init__.h"
|
||||
#endif
|
||||
|
||||
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
|
||||
@ -284,15 +284,15 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0
|
||||
STATIC void bleio_adapter_hci_init(bleio_adapter_obj_t *self) {
|
||||
mp_int_t name_len = 0;
|
||||
|
||||
#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);
|
||||
#if CIRCUITPY_OS_GETENV
|
||||
mp_obj_t name = common_hal_os_getenv("CIRCUITPY_BLE_NAME", mp_const_none);
|
||||
if (name != mp_const_none) {
|
||||
mp_arg_validate_type_string(name, MP_QSTR_CIRCUITPY_BLE_NAME);
|
||||
self->name = name;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (name_len <= 0) {
|
||||
if (!self->name) {
|
||||
name_len = sizeof(default_ble_name);
|
||||
bt_addr_t addr;
|
||||
hci_check_error(hci_read_bd_addr(&addr));
|
||||
|
@ -93,6 +93,7 @@ bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer
|
||||
void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
|
||||
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
||||
bleio_characteristic_clear_observer(self->characteristic);
|
||||
ringbuf_deinit(&self->ringbuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,13 +37,13 @@
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
|
||||
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
|
||||
if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) {
|
||||
// This shouldn't happen.
|
||||
return;
|
||||
}
|
||||
// Push all the data onto the ring buffer.
|
||||
// Make room for the new value by dropping the oldest packets first.
|
||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||
while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||
uint16_t packet_length;
|
||||
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
||||
for (uint16_t i = 0; i < packet_length; i++) {
|
||||
@ -264,5 +264,6 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
|
||||
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
||||
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
||||
bleio_characteristic_clear_observer(self->characteristic);
|
||||
ringbuf_deinit(&self->ringbuf);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
MicroPython & CircuitPython license information
|
||||
===============================================
|
||||
# MicroPython & CircuitPython License
|
||||
|
||||
The MIT License (MIT)
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2017 Damien P. George, and others
|
||||
Copyright (c) 2013-2022 Damien P. George and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -12,13 +11,13 @@ 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 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.
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -141,7 +141,7 @@ statement will ensure hardware isn't enabled longer than needed.
|
||||
Verify your device
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Whenever possible, make sure device you are talking to is the device you expect.
|
||||
Whenever possible, make sure the device you are talking to is the device you expect.
|
||||
If not, raise a RuntimeError. Beware that I2C addresses can be identical on
|
||||
different devices so read registers you know to make sure they match your
|
||||
expectation. Validating this upfront will help catch mistakes.
|
||||
@ -202,10 +202,10 @@ interchangeably with the CPython name. This is confusing. Instead, think up a
|
||||
new name that is related to the extra functionality you are adding.
|
||||
|
||||
For example, storage mounting and unmounting related functions were moved from
|
||||
``uos`` into a new `storage` module. Terminal related functions were moved into
|
||||
`multiterminal`. These names better match their functionality and do not
|
||||
conflict with CPython names. Make sure to check that you don't conflict with
|
||||
CPython libraries too. That way we can port the API to CPython in the future.
|
||||
``uos`` into a new `storage` module. These names better match their
|
||||
functionality and do not conflict with CPython names. Make sure to check that
|
||||
you don't conflict with CPython libraries too. That way we can port the API to
|
||||
CPython in the future.
|
||||
|
||||
Example
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -213,7 +213,7 @@ Example
|
||||
When adding extra functionality to CircuitPython to mimic what a normal
|
||||
operating system would do, either copy an existing CPython API (for example file
|
||||
writing) or create a separate module to achieve what you want. For example,
|
||||
mounting and unmount drives is not a part of CPython so it should be done in a
|
||||
mounting and unmounting drives is not a part of CPython so it should be done in a
|
||||
module, such as a new ``storage`` module, that is only available in CircuitPython.
|
||||
That way when someone moves the code to CPython they know what parts need to be
|
||||
adapted.
|
||||
@ -267,6 +267,14 @@ After the license comment::
|
||||
|
||||
"""
|
||||
|
||||
Version description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After the import statements::
|
||||
|
||||
__version__ = "0.0.0+auto.0"
|
||||
__repo__ = "<repo github link>"
|
||||
|
||||
|
||||
Class description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -309,7 +317,7 @@ following structure:
|
||||
|
||||
param_type
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The type of the parameter. This could be among other `int`, `float`, `str` `bool`, etc.
|
||||
The type of the parameter. This could be, among others, ``int``, ``float``, ``str``, ``bool``, etc.
|
||||
To document an object in the CircuitPython domain, you need to include a ``~`` before the
|
||||
definition as shown in the following example:
|
||||
|
||||
@ -494,6 +502,45 @@ backticks ``:class:`~adafruit_motor.servo.Servo```. You must also add the refer
|
||||
|
||||
"adafruit_motor": ("https://circuitpython.readthedocs.io/projects/motor/en/latest/", None,),
|
||||
|
||||
Use ``adafruit_register`` when possible
|
||||
--------------------------------------------------------------------------------
|
||||
`Register <https://github.com/adafruit/Adafruit_CircuitPython_Register>`_ is
|
||||
a foundational library that manages packing and unpacking data from I2C device
|
||||
registers. There is also `Register SPI <https://github.com/adafruit/Adafruit_CircuitPython_Register_SPI>`_
|
||||
for SPI devices. When possible, use one of these libraries for unpacking and
|
||||
packing registers. This ensures the packing code is shared amongst all
|
||||
registers (even across drivers). Furthermore, it simplifies device definitions
|
||||
by making them declarative (only data.)
|
||||
|
||||
Values with non-consecutive bits in a register or that represent FIFO endpoints
|
||||
may not map well to existing register classes. In unique cases like these, it is
|
||||
ok to read and write the register directly.
|
||||
|
||||
*Do not* add all registers from a datasheet upfront. Instead, only add the ones
|
||||
necessary for the functionality the driver exposes. Adding them all will lead to
|
||||
unnecessary file size and API clutter. See `this video about outside-in design
|
||||
from @tannewt <https://www.youtube.com/watch?v=3QewiyfBQh8>`_.
|
||||
|
||||
I2C Example
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from adafruit_register import i2c_bit
|
||||
from adafruit_bus_device import i2c_device
|
||||
|
||||
class HelloWorldDevice:
|
||||
"""Device with two bits to control when the words 'hello' and 'world' are lit."""
|
||||
|
||||
hello = i2c_bit.RWBit(0x0, 0x0)
|
||||
"""Bit to indicate if hello is lit."""
|
||||
|
||||
world = i2c_bit.RWBit(0x1, 0x0)
|
||||
"""Bit to indicate if world is lit."""
|
||||
|
||||
def __init__(self, i2c, device_address=0x0):
|
||||
self.i2c_device = i2c_device.I2CDevice(i2c, device_address)
|
||||
|
||||
Use BusDevice
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -668,8 +715,24 @@ when using ``const()``, keep in mind these general guide lines:
|
||||
|
||||
- Always use via an import, ex: ``from micropython import const``
|
||||
- Limit use to global (module level) variables only.
|
||||
- If user will not need access to variable, prefix name with a leading
|
||||
underscore, ex: ``_SOME_CONST``.
|
||||
- Only used when the user will not need access to variable and prefix name with
|
||||
a leading underscore, ex: ``_SOME_CONST``.
|
||||
|
||||
Example
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from adafruit_bus_device import i2c_device
|
||||
from micropython import const
|
||||
|
||||
_DEFAULT_I2C_ADDR = const(0x42)
|
||||
|
||||
class Widget:
|
||||
"""A generic widget."""
|
||||
|
||||
def __init__(self, i2c, address=_DEFAULT_I2C_ADDR):
|
||||
self.i2c_device = i2c_device.I2CDevice(i2c, address)
|
||||
|
||||
Libraries Examples
|
||||
------------------
|
||||
@ -751,6 +814,16 @@ properties.
|
||||
| ``sound_level`` | float | non-unit-specific sound level (monotonic but not actual decibels) |
|
||||
+-----------------------+-----------------------+-------------------------------------------------------------------------+
|
||||
|
||||
Driver constant naming
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
When adding variables for constant values for a driver. Do not include the
|
||||
device's name in the variable name. For example, in ``adafruit_fancy123.py``,
|
||||
variables should not start with ``FANCY123_``. Adding this prefix increases RAM
|
||||
usage and .mpy file size because variable names are preserved. User code should
|
||||
refer to these constants as ``adafruit_fancy123.HELLO_WORLD`` for clarity.
|
||||
``adafruit_fancy123.FANCY123_HELLO_WORLD`` would be overly verbose.
|
||||
|
||||
Adding native modules
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
Additional CircuitPython Libraries and Drivers on GitHub
|
||||
=========================================================
|
||||
|
||||
These are libraries and drivers available in separate GitHub repos. They are
|
||||
designed for use with CircuitPython and may or may not work with
|
||||
`MicroPython <https://micropython.org>`_.
|
||||
|
||||
|
||||
Adafruit CircuitPython Library Bundle
|
||||
--------------------------------------
|
||||
|
||||
We provide a bundle of all our libraries to ease installation of drivers and
|
||||
their dependencies. The bundle is primarily geared to the Adafruit Express line
|
||||
of boards which feature a relatively large external flash. With Express boards,
|
||||
it's easy to copy them all onto the filesystem. However, if you don't have
|
||||
enough space simply copy things over as they are needed.
|
||||
|
||||
- The Adafruit bundles are available on GitHub: <https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases>.
|
||||
|
||||
- Documentation for the bundle, which includes links to documentation for all
|
||||
libraries, is available here: <https://circuitpython.readthedocs.io/projects/bundle/en/latest/>.
|
||||
|
||||
|
||||
CircuitPython Community Library Bundle
|
||||
---------------------------------------
|
||||
|
||||
This bundle contains non-Adafruit sponsored libraries, that are written and submitted
|
||||
by members of the community.
|
||||
|
||||
- The Community bundles are available on GitHub: <https://github.com/adafruit/CircuitPython_Community_Bundle/releases>.
|
||||
|
||||
- Documentation is not available on ReadTheDocs at this time. See each library for any
|
||||
included documentation.
|
@ -6,24 +6,49 @@ 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.
|
||||
CircuitPython uses a file called ``settings.toml`` 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 ``settings.toml`` file contents
|
||||
on every access.
|
||||
|
||||
These libraries store environment variables in a ``.env`` file. Here is a simple
|
||||
example:
|
||||
CircuitPython only supports a subset of the full toml specification, see below
|
||||
for more details. The subset is very "Python-like", which is a key reason we
|
||||
selected the format.
|
||||
|
||||
.. code-block:: bash
|
||||
Due to technical limitations it probably also accepts some files that are
|
||||
not valid TOML files; bugs of this nature are subject to change (i.e., be
|
||||
fixed) without the usual deprecation period for incompatible changes.
|
||||
|
||||
KEY1='value1'
|
||||
# Comment
|
||||
KEY2='value2
|
||||
is multiple lines'
|
||||
File format example:
|
||||
|
||||
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.
|
||||
.. code-block::
|
||||
|
||||
str_key="Hello world" # with trailing comment
|
||||
int_key = 7
|
||||
unicode_key="œuvre"
|
||||
unicode_key2="\\u0153uvre" # same as above
|
||||
unicode_key3="\\U00000153uvre" # same as above
|
||||
escape_codes="supported, including \\r\\n\\"\\\\"
|
||||
# comment
|
||||
[subtable]
|
||||
subvalue="cannot retrieve this using getenv"
|
||||
|
||||
|
||||
Details of the toml language subset
|
||||
-----------------------------------
|
||||
|
||||
* The content is required to be in UTF-8 encoding
|
||||
* The supported data types are string and integer
|
||||
* Only basic strings are supported, not triple-quoted strings
|
||||
* Only integers supported by strtol. (no 0o, no 0b, no underscores 1_000, 011
|
||||
is 9, not 11)
|
||||
* Only bare keys are supported
|
||||
* Duplicate keys are not diagnosed.
|
||||
* Comments are supported
|
||||
* Only values from the "root table" can be retrieved
|
||||
* due to technical limitations, the content of multi-line
|
||||
strings can erroneously be parsed as a value.
|
||||
|
||||
CircuitPython behavior
|
||||
----------------------
|
||||
@ -35,10 +60,20 @@ CIRCUITPY_BLE_NAME
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Default BLE name the board advertises as, including for the BLE workflow.
|
||||
|
||||
CIRCUITPY_RESERVED_PSRAM
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
On boards with Espressif microcontrollers with PSRAM (also called SPIRAM), permanently reserve a portion of PSRAM for use by esp-idf.
|
||||
This storage is removed from the CircuitPython "heap" and is available for allocation by esp-idf routines in the core instead.
|
||||
Generally, only set this to a non-zero value when it is required by a specific core module.
|
||||
|
||||
CIRCUITPY_WEB_API_PASSWORD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Password required to make modifications to the board from the Web Workflow.
|
||||
|
||||
CIRCUITPY_WEB_API_PORT
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
TCP port number used for the web HTTP API. Defaults to 80 when omitted.
|
||||
|
||||
CIRCUITPY_WIFI_PASSWORD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID.
|
||||
|
@ -21,7 +21,7 @@ Full Table of Contents
|
||||
../shared-bindings/index.rst
|
||||
supported_ports.rst
|
||||
troubleshooting.rst
|
||||
drivers.rst
|
||||
libraries.rst
|
||||
workflows
|
||||
environment.rst
|
||||
|
||||
@ -48,7 +48,7 @@ Full Table of Contents
|
||||
../CONTRIBUTING
|
||||
../BUILDING
|
||||
../CODE_OF_CONDUCT
|
||||
../license.rst
|
||||
../docs/LICENSE
|
||||
../WEBUSB_README
|
||||
|
||||
Indices and tables
|
||||
|
31
docs/libraries.rst
Normal file
31
docs/libraries.rst
Normal file
@ -0,0 +1,31 @@
|
||||
Adafruit CircuitPython Libraries
|
||||
================================
|
||||
|
||||
Documentation for all Adafruit-sponsored CircuitPython libraries is at:
|
||||
<https://docs.circuitpython.org/projects/bundle/en/latest/drivers.html>.
|
||||
|
||||
|
||||
CircuitPython Library Bundles
|
||||
=============================
|
||||
|
||||
Many Python libraries, including device drivers, have been written for use with CircuitPython.
|
||||
They are maintained in separate GitHub repos, one per library.
|
||||
|
||||
Libraries are packaged in *bundles*, which are ZIP files that are snapshots in time of a group of libraries.
|
||||
|
||||
Adafruit sponsors and maintains several hundred libraries, packaged in the **Adafruit Library Bundle**.
|
||||
Adafruit-sponsored libraries are also available on <https://pypi.org>.
|
||||
|
||||
Yet other libraries are maintained by members of the CircuitPython community,
|
||||
and are packaged in the **CircuitPython Community Library Bundle**.
|
||||
|
||||
The Adafruit bundles are available on GitHub: <https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases>.
|
||||
The Community bundles are available at: <https://github.com/adafruit/CircuitPython_Community_Bundle/releases>.
|
||||
|
||||
More detailed information about the bundles, and download links for the latest bundles
|
||||
are at <https://circuitpython.org/libraries>.
|
||||
|
||||
Documentation about bundle construction is at: <https://circuitpython.readthedocs.io/projects/bundle/en/latest/>.
|
||||
|
||||
Documentation for Community Libraries is not available on ReadTheDocs at this time. See the GitHub repository
|
||||
for each library for any included documentation.
|
@ -1,323 +0,0 @@
|
||||
:mod:`uasyncio` --- asynchronous I/O scheduler
|
||||
==============================================
|
||||
|
||||
.. module:: uasyncio
|
||||
:synopsis: asynchronous I/O scheduler for writing concurrent code
|
||||
|
||||
|see_cpython_module|
|
||||
`asyncio <https://docs.python.org/3.8/library/asyncio.html>`_
|
||||
|
||||
Example::
|
||||
|
||||
import uasyncio
|
||||
|
||||
async def blink(led, period_ms):
|
||||
while True:
|
||||
led.on()
|
||||
await uasyncio.sleep_ms(5)
|
||||
led.off()
|
||||
await uasyncio.sleep_ms(period_ms)
|
||||
|
||||
async def main(led1, led2):
|
||||
uasyncio.create_task(blink(led1, 700))
|
||||
uasyncio.create_task(blink(led2, 400))
|
||||
await uasyncio.sleep_ms(10_000)
|
||||
|
||||
# Running on a pyboard
|
||||
from pyb import LED
|
||||
uasyncio.run(main(LED(1), LED(2)))
|
||||
|
||||
# Running on a generic board
|
||||
from machine import Pin
|
||||
uasyncio.run(main(Pin(1), Pin(2)))
|
||||
|
||||
Core functions
|
||||
--------------
|
||||
|
||||
.. function:: create_task(coro)
|
||||
|
||||
Create a new task from the given coroutine and schedule it to run.
|
||||
|
||||
Returns the corresponding `Task` object.
|
||||
|
||||
.. function:: current_task()
|
||||
|
||||
Return the `Task` object associated with the currently running task.
|
||||
|
||||
.. function:: run(coro)
|
||||
|
||||
Create a new task from the given coroutine and run it until it completes.
|
||||
|
||||
Returns the value returned by *coro*.
|
||||
|
||||
.. function:: sleep(t)
|
||||
|
||||
Sleep for *t* seconds (can be a float).
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. function:: sleep_ms(t)
|
||||
|
||||
Sleep for *t* milliseconds.
|
||||
|
||||
This is a coroutine, and a MicroPython extension.
|
||||
|
||||
Additional functions
|
||||
--------------------
|
||||
|
||||
.. function:: wait_for(awaitable, timeout)
|
||||
|
||||
Wait for the *awaitable* to complete, but cancel it if it takes longer
|
||||
that *timeout* seconds. If *awaitable* is not a task then a task will be
|
||||
created from it.
|
||||
|
||||
If a timeout occurs, it cancels the task and raises ``asyncio.TimeoutError``:
|
||||
this should be trapped by the caller.
|
||||
|
||||
Returns the return value of *awaitable*.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. function:: wait_for_ms(awaitable, timeout)
|
||||
|
||||
Similar to `wait_for` but *timeout* is an integer in milliseconds.
|
||||
|
||||
This is a coroutine, and a MicroPython extension.
|
||||
|
||||
.. function:: gather(*awaitables, return_exceptions=False)
|
||||
|
||||
Run all *awaitables* concurrently. Any *awaitables* that are not tasks are
|
||||
promoted to tasks.
|
||||
|
||||
Returns a list of return values of all *awaitables*.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
class Task
|
||||
----------
|
||||
|
||||
.. class:: Task()
|
||||
|
||||
This object wraps a coroutine into a running task. Tasks can be waited on
|
||||
using ``await task``, which will wait for the task to complete and return
|
||||
the return value of the task.
|
||||
|
||||
Tasks should not be created directly, rather use `create_task` to create them.
|
||||
|
||||
.. method:: Task.cancel()
|
||||
|
||||
Cancel the task by injecting a ``CancelledError`` into it. The task may
|
||||
or may not ignore this exception.
|
||||
|
||||
class Event
|
||||
-----------
|
||||
|
||||
.. class:: Event()
|
||||
|
||||
Create a new event which can be used to synchronise tasks. Events start
|
||||
in the cleared state.
|
||||
|
||||
.. method:: Event.is_set()
|
||||
|
||||
Returns ``True`` if the event is set, ``False`` otherwise.
|
||||
|
||||
.. method:: Event.set()
|
||||
|
||||
Set the event. Any tasks waiting on the event will be scheduled to run.
|
||||
|
||||
.. method:: Event.clear()
|
||||
|
||||
Clear the event.
|
||||
|
||||
.. method:: Event.wait()
|
||||
|
||||
Wait for the event to be set. If the event is already set then it returns
|
||||
immediately.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
class Lock
|
||||
----------
|
||||
|
||||
.. class:: Lock()
|
||||
|
||||
Create a new lock which can be used to coordinate tasks. Locks start in
|
||||
the unlocked state.
|
||||
|
||||
In addition to the methods below, locks can be used in an ``async with`` statement.
|
||||
|
||||
.. method:: Lock.locked()
|
||||
|
||||
Returns ``True`` if the lock is locked, otherwise ``False``.
|
||||
|
||||
.. method:: Lock.acquire()
|
||||
|
||||
Wait for the lock to be in the unlocked state and then lock it in an atomic
|
||||
way. Only one task can acquire the lock at any one time.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Lock.release()
|
||||
|
||||
Release the lock. If any tasks are waiting on the lock then the next one in the
|
||||
queue is scheduled to run and the lock remains locked. Otherwise, no tasks are
|
||||
waiting an the lock becomes unlocked.
|
||||
|
||||
TCP stream connections
|
||||
----------------------
|
||||
|
||||
.. function:: open_connection(host, port)
|
||||
|
||||
Open a TCP connection to the given *host* and *port*. The *host* address will be
|
||||
resolved using `socket.getaddrinfo`, which is currently a blocking call.
|
||||
|
||||
Returns a pair of streams: a reader and a writer stream.
|
||||
Will raise a socket-specific ``OSError`` if the host could not be resolved or if
|
||||
the connection could not be made.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. function:: start_server(callback, host, port, backlog=5)
|
||||
|
||||
Start a TCP server on the given *host* and *port*. The *callback* will be
|
||||
called with incoming, accepted connections, and be passed 2 arguments: reader
|
||||
and writer streams for the connection.
|
||||
|
||||
Returns a `Server` object.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. class:: Stream()
|
||||
|
||||
This represents a TCP stream connection. To minimise code this class implements
|
||||
both a reader and a writer, and both ``StreamReader`` and ``StreamWriter`` alias to
|
||||
this class.
|
||||
|
||||
.. method:: Stream.get_extra_info(v)
|
||||
|
||||
Get extra information about the stream, given by *v*. The valid values for *v* are:
|
||||
``peername``.
|
||||
|
||||
.. method:: Stream.close()
|
||||
|
||||
Close the stream.
|
||||
|
||||
.. method:: Stream.wait_closed()
|
||||
|
||||
Wait for the stream to close.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Stream.read(n)
|
||||
|
||||
Read up to *n* bytes and return them.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Stream.readinto(buf)
|
||||
|
||||
Read up to n bytes into *buf* with n being equal to the length of *buf*.
|
||||
|
||||
Return the number of bytes read into *buf*.
|
||||
|
||||
This is a coroutine, and a MicroPython extension.
|
||||
|
||||
.. method:: Stream.readexactly(n)
|
||||
|
||||
Read exactly *n* bytes and return them as a bytes object.
|
||||
|
||||
Raises an ``EOFError`` exception if the stream ends before reading *n* bytes.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Stream.readline()
|
||||
|
||||
Read a line and return it.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Stream.write(buf)
|
||||
|
||||
Accumulated *buf* to the output buffer. The data is only flushed when
|
||||
`Stream.drain` is called. It is recommended to call `Stream.drain` immediately
|
||||
after calling this function.
|
||||
|
||||
.. method:: Stream.drain()
|
||||
|
||||
Drain (write) all buffered output data out to the stream.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
.. class:: Server()
|
||||
|
||||
This represents the server class returned from `start_server`. It can be used
|
||||
in an ``async with`` statement to close the server upon exit.
|
||||
|
||||
.. method:: Server.close()
|
||||
|
||||
Close the server.
|
||||
|
||||
.. method:: Server.wait_closed()
|
||||
|
||||
Wait for the server to close.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
Event Loop
|
||||
----------
|
||||
|
||||
.. function:: get_event_loop()
|
||||
|
||||
Return the event loop used to schedule and run tasks. See `Loop`.
|
||||
|
||||
.. function:: new_event_loop()
|
||||
|
||||
Reset the event loop and return it.
|
||||
|
||||
Note: since MicroPython only has a single event loop this function just
|
||||
resets the loop's state, it does not create a new one.
|
||||
|
||||
.. class:: Loop()
|
||||
|
||||
This represents the object which schedules and runs tasks. It cannot be
|
||||
created, use `get_event_loop` instead.
|
||||
|
||||
.. method:: Loop.create_task(coro)
|
||||
|
||||
Create a task from the given *coro* and return the new `Task` object.
|
||||
|
||||
.. method:: Loop.run_forever()
|
||||
|
||||
Run the event loop until `stop()` is called.
|
||||
|
||||
.. method:: Loop.run_until_complete(awaitable)
|
||||
|
||||
Run the given *awaitable* until it completes. If *awaitable* is not a task
|
||||
then it will be promoted to one.
|
||||
|
||||
.. method:: Loop.stop()
|
||||
|
||||
Stop the event loop.
|
||||
|
||||
.. method:: Loop.close()
|
||||
|
||||
Close the event loop.
|
||||
|
||||
.. method:: Loop.set_exception_handler(handler)
|
||||
|
||||
Set the exception handler to call when a Task raises an exception that is not
|
||||
caught. The *handler* should accept two arguments: ``(loop, context)``.
|
||||
|
||||
.. method:: Loop.get_exception_handler()
|
||||
|
||||
Get the current exception handler. Returns the handler, or ``None`` if no
|
||||
custom handler is set.
|
||||
|
||||
.. method:: Loop.default_exception_handler(context)
|
||||
|
||||
The default exception handler that is called.
|
||||
|
||||
.. method:: Loop.call_exception_handler(context)
|
||||
|
||||
Call the current exception handler. The argument *context* is passed through and
|
||||
is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``.
|
@ -1,8 +1,11 @@
|
||||
:mod:`builtins` -- builtin functions and exceptions
|
||||
===================================================
|
||||
|
||||
.. module:: builtins
|
||||
:synopsis: builtin Python functions
|
||||
|
||||
All builtin functions and exceptions are described here. They are also
|
||||
available via ``builtins`` module.
|
||||
available via the ``builtins`` module.
|
||||
|
||||
For more information about built-ins, see the following CPython documentation:
|
||||
|
||||
@ -197,10 +200,6 @@ Exceptions
|
||||
|
||||
.. exception:: MemoryError
|
||||
|
||||
.. exception:: MpyError
|
||||
|
||||
Not a part of the CPython standard library
|
||||
|
||||
.. exception:: NameError
|
||||
|
||||
.. exception:: NotImplementedError
|
||||
|
@ -28,7 +28,7 @@ Classes
|
||||
|
||||
- The optional *flags* can be 1 to check for overflow when adding items.
|
||||
|
||||
As well as supporting `bool` and `len`, deque objects have the following
|
||||
As well as supporting ``bool`` and ``len``, deque objects have the following
|
||||
methods:
|
||||
|
||||
.. method:: deque.append(x)
|
||||
|
@ -1,60 +0,0 @@
|
||||
:mod:`hashlib` -- hashing algorithms
|
||||
=====================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: hashlib
|
||||
:synopsis: hashing algorithms
|
||||
:noindex:
|
||||
|
||||
|see_cpython_module| :mod:`cpython:hashlib`.
|
||||
|
||||
This module implements binary data hashing algorithms. The exact inventory
|
||||
of available algorithms depends on a board. Among the algorithms which may
|
||||
be implemented:
|
||||
|
||||
* SHA256 - The current generation, modern hashing algorithm (of SHA2 series).
|
||||
It is suitable for cryptographically-secure purposes. Included in the
|
||||
MicroPython core and any board is recommended to provide this, unless
|
||||
it has particular code size constraints.
|
||||
|
||||
* SHA1 - A previous generation algorithm. Not recommended for new usages,
|
||||
but SHA1 is a part of number of Internet standards and existing
|
||||
applications, so boards targeting network connectivity and
|
||||
interoperability will try to provide this.
|
||||
|
||||
* MD5 - A legacy algorithm, not considered cryptographically secure. Only
|
||||
selected boards, targeting interoperability with legacy applications,
|
||||
will offer this.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: hashlib.sha256([data])
|
||||
|
||||
Create an SHA256 hasher object and optionally feed ``data`` into it.
|
||||
|
||||
.. class:: hashlib.sha1([data])
|
||||
|
||||
Create an SHA1 hasher object and optionally feed ``data`` into it.
|
||||
|
||||
.. class:: hashlib.md5([data])
|
||||
|
||||
Create an MD5 hasher object and optionally feed ``data`` into it.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: hash.update(data)
|
||||
|
||||
Feed more binary data into hash.
|
||||
|
||||
.. method:: hash.digest()
|
||||
|
||||
Return hash for all data passed through hash, as a bytes object. After this
|
||||
method is called, more data cannot be fed into the hash any longer.
|
||||
|
||||
.. method:: hash.hexdigest()
|
||||
|
||||
This method is NOT implemented. Use ``binascii.hexlify(hash.digest())``
|
||||
to achieve a similar effect.
|
@ -19,7 +19,7 @@ limited flash memory, usually on non-Express builds:
|
||||
``binascii``, ``errno``, ``json``, ``re``.
|
||||
|
||||
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
||||
``ctypes``, ``hashlib``, ``zlib``.
|
||||
``ctypes``
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
@ -31,15 +31,12 @@ These libraries are not currently enabled in any CircuitPython build, but may be
|
||||
collections.rst
|
||||
errno.rst
|
||||
gc.rst
|
||||
hashlib.rst
|
||||
io.rst
|
||||
json.rst
|
||||
re.rst
|
||||
sys.rst
|
||||
asyncio.rst
|
||||
ctypes.rst
|
||||
select.rst
|
||||
zlib.rst
|
||||
|
||||
Omitted functions in the ``string`` library
|
||||
-------------------------------------------
|
||||
|
@ -76,7 +76,7 @@ Functions
|
||||
.. function:: heap_locked()
|
||||
|
||||
Lock or unlock the heap. When locked no memory allocation can occur and a
|
||||
`MemoryError` will be raised if any heap allocation is attempted.
|
||||
``MemoryError`` will be raised if any heap allocation is attempted.
|
||||
`heap_locked()` returns a true value if the heap is currently locked.
|
||||
|
||||
These functions can be nested, ie `heap_lock()` can be called multiple times
|
||||
|
@ -1,42 +0,0 @@
|
||||
:mod:`zlib` -- zlib decompression
|
||||
=================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: zlib
|
||||
:synopsis: zlib decompression
|
||||
:noindex:
|
||||
|
||||
|see_cpython_module| :mod:`cpython:zlib`.
|
||||
|
||||
This module allows to decompress binary data compressed with
|
||||
`DEFLATE algorithm <https://en.wikipedia.org/wiki/DEFLATE>`_
|
||||
(commonly used in zlib library and gzip archiver). Compression
|
||||
is not yet implemented.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: decompress(data, wbits=0, bufsize=0, /)
|
||||
|
||||
Return decompressed *data* as bytes. *wbits* is DEFLATE dictionary window
|
||||
size used during compression (8-15, the dictionary size is power of 2 of
|
||||
that value). Additionally, if value is positive, *data* is assumed to be
|
||||
zlib stream (with zlib header). Otherwise, if it's negative, it's assumed
|
||||
to be raw DEFLATE stream. *bufsize* parameter is for compatibility with
|
||||
CPython and is ignored.
|
||||
|
||||
.. class:: DecompIO(stream, wbits=0, /)
|
||||
:noindex:
|
||||
|
||||
Create a ``stream`` wrapper which allows transparent decompression of
|
||||
compressed data in another *stream*. This allows to process compressed
|
||||
streams with data larger than available heap size. In addition to
|
||||
values described in :func:`decompress`, *wbits* may take values
|
||||
24..31 (16 + 8..15), meaning that input stream has gzip header.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This class is MicroPython extension. It's included on provisional
|
||||
basis and may be changed considerably or removed in later versions.
|
@ -71,7 +71,7 @@ as a natural "TODO" list. An example minimal build list is shown below:
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_I2CTARGET = 0
|
||||
# Requires SPI, PulseIO (stub ok):
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
|
||||
|
@ -90,7 +90,6 @@ shared-bindings/microcontroller/Pin.rst shared-bindings/microcontroller/#microco
|
||||
shared-bindings/microcontroller/Processor.rst shared-bindings/microcontroller/#microcontroller.Processor
|
||||
shared-bindings/microcontroller/RunMode.rst shared-bindings/microcontroller/#microcontroller.RunMode
|
||||
shared-bindings/microcontroller/__init__.rst shared-bindings/microcontroller/
|
||||
shared-bindings/multiterminal/__init__.rst shared-bindings/multiterminal/
|
||||
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
|
||||
|
@ -27,12 +27,13 @@ import pathlib
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import functools
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
SUPPORTED_PORTS = ['atmel-samd', 'broadcom', 'cxd56', 'espressif', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm']
|
||||
|
||||
aliases_by_board = {
|
||||
ALIASES_BY_BOARD = {
|
||||
"circuitplayground_express": [
|
||||
"circuitplayground_express_4h",
|
||||
"circuitplayground_express_digikey_pycon2019",
|
||||
@ -40,10 +41,9 @@ aliases_by_board = {
|
||||
"pybadge": ["edgebadge"],
|
||||
"pyportal": ["pyportal_pynt"],
|
||||
"gemma_m0": ["gemma_m0_pycon2018"],
|
||||
"pewpew10": ["pewpew13"],
|
||||
}
|
||||
|
||||
aliases_brand_names = {
|
||||
ALIASES_BRAND_NAMES = {
|
||||
"circuitplayground_express_4h":
|
||||
"Adafruit Circuit Playground Express 4-H",
|
||||
"circuitplayground_express_digikey_pycon2019":
|
||||
@ -54,38 +54,73 @@ aliases_brand_names = {
|
||||
"Adafruit PyPortal Pynt",
|
||||
"gemma_m0_pycon2018":
|
||||
"Adafruit Gemma M0 PyCon 2018",
|
||||
"pewpew13":
|
||||
"PewPew 13",
|
||||
}
|
||||
|
||||
additional_modules = {
|
||||
"fontio": "CIRCUITPY_DISPLAYIO",
|
||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||
ADDITIONAL_MODULES = {
|
||||
"_asyncio": "MICROPY_PY_UASYNCIO",
|
||||
"adafruit_bus_device": "CIRCUITPY_BUSDEVICE",
|
||||
"adafruit_pixelbuf": "CIRCUITPY_PIXELBUF",
|
||||
"array": "CIRCUITPY_ARRAY",
|
||||
# always available, so depend on something that's always 1.
|
||||
"builtins": "CIRCUITPY",
|
||||
"collections": "CIRCUITPY_COLLECTIONS",
|
||||
"fontio": "CIRCUITPY_DISPLAYIO",
|
||||
"io": "CIRCUITPY_IO",
|
||||
"select": "MICROPY_PY_USELECT_SELECT",
|
||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||
"sys": "CIRCUITPY_SYS",
|
||||
"usb": "CIRCUITPY_USB_HOST",
|
||||
}
|
||||
|
||||
frozen_excludes = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
|
||||
MODULES_NOT_IN_SHARED_BINDINGS = ["_asyncio", "array", "binascii", "builtins", "collections", "errno", "json", "re", "select", "sys", "ulab"]
|
||||
|
||||
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
|
||||
"""Files and dirs at the root of a frozen directory that should be ignored.
|
||||
This is the same list as in the preprocess_frozen_modules script."""
|
||||
|
||||
repository_urls = {}
|
||||
"""Cache of repository URLs for frozen modules."""
|
||||
|
||||
def get_circuitpython_root_dir():
|
||||
""" The path to the root './circuitpython' directory
|
||||
"""
|
||||
file_path = pathlib.Path(__file__).resolve()
|
||||
root_dir = file_path.parent.parent
|
||||
root_dir = pathlib.Path(__file__).resolve().parent.parent
|
||||
|
||||
def get_circuitpython_root_dir():
|
||||
""" The path to the root './circuitpython' directory.
|
||||
"""
|
||||
return root_dir
|
||||
|
||||
def get_shared_bindings():
|
||||
""" Get a list of modules in shared-bindings based on folder names
|
||||
""" Get a list of modules in shared-bindings based on folder names.
|
||||
"""
|
||||
shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings"
|
||||
return [item.name for item in shared_bindings_dir.iterdir()] + ["binascii", "errno", "json", "re", "ulab"]
|
||||
return [item.name for item in shared_bindings_dir.iterdir()] + MODULES_NOT_IN_SHARED_BINDINGS
|
||||
|
||||
|
||||
def get_board_mapping():
|
||||
"""
|
||||
Compiles the list of boards from the directories, with aliases and mapping
|
||||
to the port.
|
||||
"""
|
||||
boards = {}
|
||||
for port in SUPPORTED_PORTS:
|
||||
board_path = root_dir / "ports" / port / "boards"
|
||||
for board_path in os.scandir(board_path):
|
||||
if board_path.is_dir():
|
||||
board_files = os.listdir(board_path.path)
|
||||
board_id = board_path.name
|
||||
aliases = ALIASES_BY_BOARD.get(board_path.name, [])
|
||||
boards[board_id] = {
|
||||
"port": port,
|
||||
"download_count": 0,
|
||||
"aliases": aliases,
|
||||
}
|
||||
for alias in aliases:
|
||||
boards[alias] = {
|
||||
"port": port,
|
||||
"download_count": 0,
|
||||
"alias": True,
|
||||
"aliases": [],
|
||||
}
|
||||
return boards
|
||||
|
||||
|
||||
def read_mpconfig():
|
||||
@ -112,8 +147,8 @@ def build_module_map():
|
||||
full_build = False
|
||||
for module in modules:
|
||||
full_name = module
|
||||
if module in additional_modules:
|
||||
search_identifier = additional_modules[module]
|
||||
if module in ADDITIONAL_MODULES:
|
||||
search_identifier = ADDITIONAL_MODULES[module]
|
||||
else:
|
||||
search_identifier = 'CIRCUITPY_'+module.lstrip("_").upper()
|
||||
re_pattern = f"{re.escape(search_identifier)}\s*\??=\s*(.+)"
|
||||
@ -204,27 +239,33 @@ def get_repository_url(directory):
|
||||
repository_urls[directory] = path
|
||||
return path
|
||||
|
||||
def frozen_modules_from_dirs(frozen_mpy_dirs):
|
||||
def frozen_modules_from_dirs(frozen_mpy_dirs, withurl):
|
||||
"""
|
||||
Go through the list of frozen directories and extract the python modules.
|
||||
Paths are of the type:
|
||||
$(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground
|
||||
$(TOP)/frozen/circuitpython-stage/meowbit
|
||||
Python modules are at the root of the path, and are python files or directories
|
||||
containing python files. Except the ones in the frozen_excludes list.
|
||||
containing python files. Except the ones in the FROZEN_EXCLUDES list.
|
||||
"""
|
||||
frozen_modules = []
|
||||
for frozen_path in filter(lambda x: x, frozen_mpy_dirs.split(" ")):
|
||||
source_dir = get_circuitpython_root_dir() / frozen_path[7:]
|
||||
url_repository = get_repository_url(source_dir)
|
||||
for sub in source_dir.glob("*"):
|
||||
if sub.name in frozen_excludes:
|
||||
if sub.name in FROZEN_EXCLUDES:
|
||||
continue
|
||||
if sub.name.endswith(".py"):
|
||||
if withurl:
|
||||
frozen_modules.append((sub.name[:-3], url_repository))
|
||||
else:
|
||||
frozen_modules.append(sub.name[:-3])
|
||||
continue
|
||||
if next(sub.glob("**/*.py"), None): # tests if not empty
|
||||
if withurl:
|
||||
frozen_modules.append((sub.name, url_repository))
|
||||
else:
|
||||
frozen_modules.append(sub.name)
|
||||
return frozen_modules
|
||||
|
||||
def lookup_setting(settings, key, default=''):
|
||||
@ -235,6 +276,7 @@ def lookup_setting(settings, key, default=''):
|
||||
key = value[2:-1]
|
||||
return value
|
||||
|
||||
@functools.cache
|
||||
def all_ports_all_boards(ports=SUPPORTED_PORTS):
|
||||
for port in ports:
|
||||
|
||||
@ -244,7 +286,7 @@ def all_ports_all_boards(ports=SUPPORTED_PORTS):
|
||||
continue
|
||||
yield (port, entry)
|
||||
|
||||
def support_matrix_by_board(use_branded_name=True):
|
||||
def support_matrix_by_board(use_branded_name=True, withurl=True):
|
||||
""" Compiles a list of the available core modules available for each
|
||||
board.
|
||||
"""
|
||||
@ -272,29 +314,49 @@ def support_matrix_by_board(use_branded_name=True):
|
||||
board_modules.append(base[module]['name'])
|
||||
board_modules.sort()
|
||||
|
||||
if "CIRCUITPY_BUILD_EXTENSIONS" in settings:
|
||||
board_extensions = [
|
||||
extension.strip() for extension in
|
||||
settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",")
|
||||
]
|
||||
else:
|
||||
raise OSError(f"Board extensions undefined: {board_name}.")
|
||||
|
||||
frozen_modules = []
|
||||
if "FROZEN_MPY_DIRS" in settings:
|
||||
frozen_modules = frozen_modules_from_dirs(settings["FROZEN_MPY_DIRS"])
|
||||
frozen_modules = frozen_modules_from_dirs(settings["FROZEN_MPY_DIRS"], withurl)
|
||||
if frozen_modules:
|
||||
frozen_modules.sort()
|
||||
|
||||
# generate alias boards too
|
||||
board_matrix = [(board_name, (board_modules, frozen_modules))]
|
||||
if entry.name in aliases_by_board:
|
||||
for alias in aliases_by_board[entry.name]:
|
||||
board_matrix = [(
|
||||
board_name, {
|
||||
"modules": board_modules,
|
||||
"frozen_libraries": frozen_modules,
|
||||
"extensions": board_extensions,
|
||||
}
|
||||
)]
|
||||
if entry.name in ALIASES_BY_BOARD:
|
||||
for alias in ALIASES_BY_BOARD[entry.name]:
|
||||
if use_branded_name:
|
||||
if alias in aliases_brand_names:
|
||||
alias = aliases_brand_names[alias]
|
||||
if alias in ALIASES_BRAND_NAMES:
|
||||
alias = ALIASES_BRAND_NAMES[alias]
|
||||
else:
|
||||
alias = alias.replace("_"," ").title()
|
||||
board_matrix.append( (alias, (board_modules, frozen_modules)) )
|
||||
board_matrix.append((
|
||||
alias, {
|
||||
"modules": board_modules,
|
||||
"frozen_libraries": frozen_modules,
|
||||
"extensions": board_extensions,
|
||||
},
|
||||
))
|
||||
|
||||
return board_matrix # this is now a list of (board,modules)
|
||||
|
||||
executor = ThreadPoolExecutor(max_workers=os.cpu_count())
|
||||
mapped_exec = executor.map(support_matrix, all_ports_all_boards())
|
||||
# flatmap with comprehensions
|
||||
boards = dict(sorted([board for matrix in mapped_exec for board in matrix]))
|
||||
boards = dict(sorted([board for matrix in mapped_exec for board in matrix], key=lambda x: x[0]))
|
||||
|
||||
return boards
|
||||
|
||||
|
@ -46,7 +46,7 @@ connection, the central device can discover two default services. One for file t
|
||||
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
|
||||
can be put in the `settings.toml` 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
|
||||
@ -69,20 +69,23 @@ 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
|
||||
The web workflow is depends on adding Wi-Fi credentials into the `settings.toml` 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.
|
||||
is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS.
|
||||
|
||||
Here is an example `/.env`:
|
||||
Here is an example `/settings.toml`:
|
||||
|
||||
```bash
|
||||
# To auto-connect to Wi-Fi
|
||||
CIRCUITPY_WIFI_SSID='scottswifi'
|
||||
CIRCUITPY_WIFI_PASSWORD='secretpassword'
|
||||
CIRCUITPY_WIFI_SSID="scottswifi"
|
||||
CIRCUITPY_WIFI_PASSWORD="secretpassword"
|
||||
|
||||
# To enable modifying files from the web. Change this too!
|
||||
CIRCUITPY_WEB_API_PASSWORD='passw0rd'
|
||||
# Leave the User field blank in the browser.
|
||||
CIRCUITPY_WEB_API_PASSWORD="passw0rd"
|
||||
|
||||
CIRCUITPY_WEB_API_PORT=80
|
||||
```
|
||||
|
||||
MDNS is used to resolve [`circuitpython.local`](http://circuitpython.local) to a device specific
|
||||
@ -119,9 +122,9 @@ The web server will allow requests from `cpy-XXXXXX.local`, `127.0.0.1`, the dev
|
||||
### 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.
|
||||
a password with something important. The user field is left blank.
|
||||
|
||||
The password is taken from `/.env` with the key `CIRCUITPY_WEB_API_PASSWORD`. If this is unset, the
|
||||
The password is taken from `settings.toml` 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`.
|
||||
|
||||
@ -135,7 +138,7 @@ root will be returned.
|
||||
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.
|
||||
* `Access-Control-Allow-Methods` - Varies with USB state. `GET, OPTIONS` when USB is active. `GET, OPTIONS, PUT, DELETE, MOVE` otherwise.
|
||||
|
||||
Example:
|
||||
|
||||
@ -199,6 +202,24 @@ Example:
|
||||
curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
|
||||
```
|
||||
|
||||
##### Move
|
||||
Moves the directory at the given path to ``X-Destination``. Also known as rename.
|
||||
|
||||
The custom `X-Destination` header stores the destination path of the directory.
|
||||
|
||||
* `201 Created` - Directory renamed
|
||||
* `401 Unauthorized` - Incorrect password
|
||||
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
||||
* `404 Not Found` - Source directory not found or destination path is missing
|
||||
* `409 Conflict` - USB is active and preventing file system modification
|
||||
* `412 Precondition Failed` - The destination path is already in use
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello2/" -L --location-trusted http://circuitpython.local/fs/lib/hello/
|
||||
```
|
||||
|
||||
##### DELETE
|
||||
Deletes the directory and all of its contents.
|
||||
|
||||
@ -211,7 +232,7 @@ Deletes the directory and all of its contents.
|
||||
Example:
|
||||
|
||||
```sh
|
||||
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world/
|
||||
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello2/world/
|
||||
```
|
||||
|
||||
|
||||
@ -267,6 +288,25 @@ curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hel
|
||||
```
|
||||
|
||||
|
||||
##### Move
|
||||
Moves the file at the given path to the ``X-Destination``. Also known as rename.
|
||||
|
||||
The custom `X-Destination` header stores the destination path of the file.
|
||||
|
||||
* `201 Created` - File renamed
|
||||
* `401 Unauthorized` - Incorrect password
|
||||
* `403 Forbidden` - No `CIRCUITPY_WEB_API_PASSWORD` set
|
||||
* `404 Not Found` - Source file not found or destination path is missing
|
||||
* `409 Conflict` - USB is active and preventing file system modification
|
||||
* `412 Precondition Failed` - The destination path is already in use
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
curl -v -u :passw0rd -X MOVE -H "X-Destination: /fs/lib/hello/world2.txt" -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
|
||||
```
|
||||
|
||||
|
||||
##### DELETE
|
||||
Deletes the file.
|
||||
|
||||
@ -280,7 +320,7 @@ Deletes the file.
|
||||
Example:
|
||||
|
||||
```sh
|
||||
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world.txt
|
||||
curl -v -u :passw0rd -X DELETE -L --location-trusted http://circuitpython.local/fs/lib/hello/world2.txt
|
||||
```
|
||||
|
||||
### `/cp/`
|
||||
@ -365,6 +405,12 @@ curl -v -L http://circuitpython.local/cp/version.json
|
||||
}
|
||||
```
|
||||
|
||||
#### `/code/`
|
||||
|
||||
The `/code/` page returns a small static html page that will pull in and load the full code editor from
|
||||
[code.circuitpython.org](https://code.circuitpython.org) for a full code editor experience. Because most
|
||||
of the resources reside online instead of the device, an active internet connection is required.
|
||||
|
||||
### Static files
|
||||
|
||||
* `/favicon.ico` - Blinka
|
||||
|
@ -70,24 +70,21 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
|
||||
/******************************************************************************/
|
||||
// Ticks for task ordering in pairing heap
|
||||
|
||||
#if !CIRCUITPY || (defined(__unix__) || defined(__APPLE__))
|
||||
STATIC mp_obj_t ticks(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
|
||||
}
|
||||
|
||||
STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) {
|
||||
mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in);
|
||||
mp_uint_t t1 = MP_OBJ_SMALL_INT_VALUE(t1_in);
|
||||
mp_int_t diff = ((t1 - t0 + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1))
|
||||
- MICROPY_PY_UTIME_TICKS_PERIOD / 2;
|
||||
return diff;
|
||||
}
|
||||
#else
|
||||
#define _TICKS_PERIOD (1lu << 29)
|
||||
#define _TICKS_MAX (_TICKS_PERIOD - 1)
|
||||
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
|
||||
|
||||
#if !CIRCUITPY || (defined(__unix__) || defined(__APPLE__))
|
||||
STATIC mp_obj_t ticks(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & _TICKS_MAX);
|
||||
}
|
||||
#else
|
||||
// We don't share the implementation above because our supervisor_ticks_ms
|
||||
// starts the epoch about 65 seconds before the first overflow (see
|
||||
// shared-bindings/supervisor/__init__.c). We assume/require that
|
||||
// supervisor.ticks_ms is picked as the ticks implementation under
|
||||
// CircuitPython for the Python-coded bits of asyncio.
|
||||
#define ticks() supervisor_ticks_ms()
|
||||
#endif
|
||||
|
||||
STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) {
|
||||
mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in);
|
||||
@ -95,7 +92,6 @@ STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) {
|
||||
mp_int_t diff = ((t1 - t0 + _TICKS_HALFPERIOD) & _TICKS_MAX) - _TICKS_HALFPERIOD;
|
||||
return diff;
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
|
||||
mp_obj_task_t *t1 = (mp_obj_task_t *)n1;
|
||||
@ -302,8 +298,13 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
||||
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (TASK_IS_DONE(self)) {
|
||||
if (self->data == mp_const_none) {
|
||||
// Task finished but has already been sent to the loop's exception handler.
|
||||
mp_raise_StopIteration(MP_OBJ_NULL);
|
||||
} else {
|
||||
// Task finished, raise return value to caller so it can continue.
|
||||
nlr_raise(self->data);
|
||||
}
|
||||
} else {
|
||||
// Put calling task on waiting queue.
|
||||
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
|
||||
|
@ -9,13 +9,14 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/ioctl.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
|
||||
// Flags for poll()
|
||||
#define FLAG_ONESHOT (1)
|
||||
@ -230,6 +231,9 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
|
||||
break;
|
||||
}
|
||||
RUN_BACKGROUND_TASKS;
|
||||
if (mp_hal_is_interrupted()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return n_ready;
|
||||
|
@ -141,6 +141,10 @@ class Task:
|
||||
|
||||
def __next__(self):
|
||||
if not self.state:
|
||||
if self.data is None:
|
||||
# Task finished but has already been sent to the loop's exception handler.
|
||||
raise StopIteration
|
||||
else:
|
||||
# Task finished, raise return value to caller so it can continue.
|
||||
raise self.data
|
||||
else:
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 346c936e14c6ea3a8d3d65cb1fa46202dc92999d
|
||||
Subproject commit f2dd2230c4fdf1aa5c7a160782efdde18e8204bb
|
@ -225,22 +225,7 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
|
||||
const char *old_path = mp_obj_str_get_str(path_in);
|
||||
const char *new_path = mp_obj_str_get_str(path_out);
|
||||
|
||||
// Check to see if we're moving a directory into itself. This occurs when we're moving a
|
||||
// directory where the old path is a prefix of the new and the next character is a "/" and thus
|
||||
// preserves the original directory name.
|
||||
FILINFO fno;
|
||||
FRESULT res = f_stat(&self->fatfs, old_path, &fno);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
if ((fno.fattrib & AM_DIR) != 0 &&
|
||||
strlen(new_path) > strlen(old_path) &&
|
||||
new_path[strlen(old_path)] == '/' &&
|
||||
strncmp(old_path, new_path, strlen(old_path)) == 0) {
|
||||
mp_raise_OSError(MP_EINVAL);
|
||||
}
|
||||
|
||||
res = f_rename(&self->fatfs, old_path, new_path);
|
||||
FRESULT res = f_rename(&self->fatfs, old_path, new_path);
|
||||
if (res == FR_EXIST) {
|
||||
// if new_path exists then try removing it (but only if it's a file)
|
||||
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute
|
||||
@ -415,6 +400,47 @@ STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
|
||||
|
||||
STATIC mp_obj_t vfs_fat_utime(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t times_in) {
|
||||
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
if (!mp_obj_is_tuple_compatible(times_in)) {
|
||||
mp_raise_type_arg(&mp_type_TypeError, times_in);
|
||||
}
|
||||
|
||||
mp_obj_t *otimes;
|
||||
mp_obj_get_array_fixed_n(times_in, 2, &otimes);
|
||||
|
||||
// Validate that both elements of the tuple are int and discard the second one
|
||||
int time[2];
|
||||
time[0] = mp_obj_get_int(otimes[0]);
|
||||
time[1] = mp_obj_get_int(otimes[1]);
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_epoch_to_struct_time(time[0], &tm);
|
||||
|
||||
FILINFO fno;
|
||||
fno.fdate = (WORD)(((tm.tm_year - 1980) * 512U) | tm.tm_mon * 32U | tm.tm_mday);
|
||||
fno.ftime = (WORD)(tm.tm_hour * 2048U | tm.tm_min * 32U | tm.tm_sec / 2U);
|
||||
FRESULT res = f_utime(&self->fatfs, path, &fno);
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError_fresult(res);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_utime_obj, vfs_fat_utime);
|
||||
|
||||
STATIC mp_obj_t vfs_fat_getreadonly(mp_obj_t self_in) {
|
||||
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(!filesystem_is_writable_by_python(self));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getreadonly_obj, vfs_fat_getreadonly);
|
||||
STATIC const mp_obj_property_t fat_vfs_readonly_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&fat_vfs_getreadonly_obj,
|
||||
MP_ROM_NONE,
|
||||
MP_ROM_NONE},
|
||||
};
|
||||
|
||||
#if MICROPY_FATFS_USE_LABEL
|
||||
STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) {
|
||||
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
@ -466,6 +492,8 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_fat_mount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&fat_vfs_utime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readonly), MP_ROM_PTR(&fat_vfs_readonly_obj) },
|
||||
#if MICROPY_FATFS_USE_LABEL
|
||||
{ MP_ROM_QSTR(MP_QSTR_label), MP_ROM_PTR(&fat_vfs_label_obj) },
|
||||
#endif
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 13856be616eee2eb84280b7c4914951c1ddbfd36
|
||||
Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93
|
@ -1 +1 @@
|
||||
Subproject commit 7d9635ba1dda31ce45b84519c4da76ff86d0debe
|
||||
Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e
|
@ -1 +1 @@
|
||||
Subproject commit e5cf8206c0173228252ae74367cab85b0531488e
|
||||
Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86
|
@ -1 +1 @@
|
||||
Subproject commit 9addf6a26fef3a32c78d574c66452b6210eca5c5
|
||||
Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0
|
@ -1 +1 @@
|
||||
Subproject commit 843def7daee741c8fb04fe21c3c7b98f22862471
|
||||
Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc
|
@ -1 +1 @@
|
||||
Subproject commit 0a045871d3da681d1c9c9578f09174bfc6d84f1d
|
||||
Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947
|
@ -1 +1 @@
|
||||
Subproject commit 6a429bcd0e6b22ee181197ce0477ae70f5adb80d
|
||||
Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a
|
@ -1 +1 @@
|
||||
Subproject commit 22931594bc52ab259eaf313d26219a507703c315
|
||||
Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216
|
@ -1 +1 @@
|
||||
Subproject commit cdef09114d2b43d2e461d066a5b56697ab567abc
|
||||
Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39
|
@ -1 +1 @@
|
||||
Subproject commit bb9cb75e15b4bfce3063a94b40dfad2375d5605e
|
||||
Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a
|
@ -1 +1 @@
|
||||
Subproject commit f9469d26ed9eb95d43982de88c035ac3862dd258
|
||||
Subproject commit 187279a95e5cdd634d233af59352558cea4c1227
|
@ -1 +1 @@
|
||||
Subproject commit f3d504be1dc82cc4a8e4ea9b38bd5c2ce74d59ba
|
||||
Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1
|
@ -1 +1 @@
|
||||
Subproject commit 2ea025b1b68b0be95a0514732d4bc623f313fd75
|
||||
Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db
|
@ -1 +1 @@
|
||||
Subproject commit b637c47423eb85233ba614424aadadace37fcfb1
|
||||
Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f
|
@ -1 +1 @@
|
||||
Subproject commit 47cc91474823677218239b5b37901590755cac4c
|
||||
Subproject commit 93c7e0ed55e7ed011908ac9a1c0f8228f0f4323b
|
@ -1 +1 @@
|
||||
Subproject commit a2491a806b636f66caf670527c49b864923f125c
|
||||
Subproject commit 340c62ef6ce867b3924d166afc3d2a171680f799
|
@ -1 +1 @@
|
||||
Subproject commit b4a0461889ead5da69f4ed6d0118276b01613981
|
||||
Subproject commit 5433ba3760ca605267223de883a44cb8394f40a5
|
@ -1 +1 @@
|
||||
Subproject commit 72367f37cd221c7af7822ba3a9cd21cd3cd70292
|
||||
Subproject commit 38bd02f014403954ab52154e3877e502d83862dc
|
@ -1 +1 @@
|
||||
Subproject commit a06c8a116e5767a8481b9018239fe729e01760a6
|
||||
Subproject commit 240fe51935f4a9def33ef347d40b13862a60b7ac
|
@ -1 +1 @@
|
||||
Subproject commit 5acf8a850d98789a79fe37836b2ac7b623d95913
|
||||
Subproject commit d689ca77c67806484037e00110c669cf55846b6e
|
@ -1 +1 @@
|
||||
Subproject commit d3f9adce6e48d37222ef171a280cfa3122faf15b
|
||||
Subproject commit e38bf1f9cf1e8faeb7d15a1d10674fb2c0a81e72
|
@ -1 +1 @@
|
||||
Subproject commit df61e7b0be9dc0c6a1bbe60f526fbdc01b6c2819
|
||||
Subproject commit 9c3de3abce00b50ba936f4f8daad0a8a6bee34a6
|
@ -1 +1 @@
|
||||
Subproject commit 015eb1ccd5eb5364d8e1cf20358e7dcda9f12efc
|
||||
Subproject commit 9516aa97e9216eac2b229fbb7dac34fa60c347c4
|
@ -1 +1 @@
|
||||
Subproject commit 217af2bc7de658ff2f6380a066d99a149e69693e
|
||||
Subproject commit 759c5c348878932adc5fcc9e4f3b3f570b43e17f
|
@ -1 +1 @@
|
||||
Subproject commit 1c39469bac98eea022af695ac42e5096dae6130c
|
||||
Subproject commit 74a1c261103cda43172053ff2370777255b9bf8d
|
@ -1 +1 @@
|
||||
Subproject commit 74ea48f7a5d85591f5af804cacb57e9cfaab46c6
|
||||
Subproject commit af1cba8a7e4e3950fcc5367e9c55a024d9ab9f64
|
@ -1 +1 @@
|
||||
Subproject commit 13cdb9912ba31f6e267f1afb9f71fddf5b1c139c
|
||||
Subproject commit c46c59e3004817c708c78c59d247b02161c6bf06
|
@ -1 +1 @@
|
||||
Subproject commit d1e8ac7ad9dcd65ab83749db3e5c96ffee80ebb7
|
||||
Subproject commit 46a49205f3f14546273dd1267e66cad82f03986c
|
@ -1 +1 @@
|
||||
Subproject commit b168b28fc58973cf20269cc87a655d7812659fd0
|
||||
Subproject commit 558fff7223178eae6228e5262f3a08d3a4101394
|
@ -1 +1 @@
|
||||
Subproject commit 332143d4ca5762d2d351ceb170c0b4e37dd42793
|
||||
Subproject commit eb17bffa757dc8c0a53fe9e61c45246c06418099
|
1
frozen/Adafruit_CircuitPython_SSD1680
Submodule
1
frozen/Adafruit_CircuitPython_SSD1680
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 91b6867aca2b0511571fed14ab051d37f1f1544c
|
@ -1 +1 @@
|
||||
Subproject commit 995959d5dca23fbe49590700d1aa26a96dca1df7
|
||||
Subproject commit e23c4871456cdf0ef1bfb59d1c2f6e38b7b640ee
|
@ -1 +1 @@
|
||||
Subproject commit d238fe99e24ea4cdb472f1d8a9c99dd189b0aeca
|
||||
Subproject commit eac33b430b0cbe1f6f583000f6b29f75bfe8507e
|
@ -1 +1 @@
|
||||
Subproject commit 632655b8f5f6f62e3b4d0b6161213634e0ae74e9
|
||||
Subproject commit dc605bb22914d77d80c5342cbb4c10f773aede95
|
@ -1 +1 @@
|
||||
Subproject commit 3816a4f4c997b03d4a7ebfe35a617d1e50124b04
|
||||
Subproject commit 43a4f15d604919d6e143e975a85abf7b96a4061d
|
@ -1 +1 @@
|
||||
Subproject commit 6757c5b37cf26458448930042cb0a41f8ad0a5ef
|
||||
Subproject commit 2634ca0163020bebec300fcca6e0b5afcdc655b8
|
1
frozen/Adafruit_CircuitPython_UC8151D
Submodule
1
frozen/Adafruit_CircuitPython_UC8151D
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b6d9f852f50b489615f3f357f9758d0073335334
|
@ -1 +1 @@
|
||||
Subproject commit c496cfb5768cd506d61100284fdab94dd439ec3b
|
||||
Subproject commit 596cc896e5c8815caa2a6f405560833193848149
|
@ -1 +1 @@
|
||||
Subproject commit 148345d232c83133de3649fb70b471f11501b3d2
|
||||
Subproject commit d4ff0388f3e3af2745864f2c3e5926f500673a40
|
@ -1 +1 @@
|
||||
Subproject commit 3bdd335452ff14a53d1e840de043e3159cb3b829
|
||||
Subproject commit 4124dfbdaadce1966f457d7d6c6984e9832999bf
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user